package com.lanhai.action;

import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;

import com.lanhai.Main;
import com.lanhai.MainAction;
import com.lanhai.enums.AgvState;
import com.lanhai.enums.CaFlag;
import com.lanhai.enums.GpType;
import com.lanhai.enums.LoadState;
import com.lanhai.enums.Step;
import com.lanhai.enums.TransferType;
import com.lanhai.javaBean.GuidepostBean;
import com.lanhai.javaBean.ParkBean;
import com.lanhai.model.Agv;
import com.lanhai.model.CacheShelf;
import com.lanhai.model.ControlArea;
import com.lanhai.model.ControlRunAgv;
import com.lanhai.model.FreeArea;
import com.lanhai.model.Guidepost;
import com.lanhai.model.LimitArea;
import com.lanhai.model.Park;
import com.lanhai.model.Path;
import com.lanhai.model.Station;
import com.lanhai.model.TrafficWait;
import com.lanhai.utils.CommandUtil;
import com.lanhai.utils.DateUtil;
import com.lanhai.utils.HexUtil;
import com.lanhai.utils.RegionUtil;

/**
 * 调度AGV 2019-9-7
 */
public class AgvDispatchAction {
	private static final Logger logger = Logger.getLogger(AgvDispatchAction.class);
	private static final Logger agvlog = Logger.getLogger("agvlog");

	private static int NO_BIT = 1;// 车号位
	private static int STATE_BIT = 2;// AGV状态
	private static int BATTERY_BIT = 10;// 电池余量
	private static int LOAD_BIT = 11;// AGV的负载状况
	public static double RADIUS = 30;// 座标范围半径
	private MainAction mainAction;

	/**
	 * 初始化
	 */
	public void init(MainAction deal) {
		mainAction = deal;
	}

	/**
	 * 处理AGV数据
	 * 
	 * @param data
	 */
	public void handle(byte[] recData) {
		/**
		 * 根据系统逻辑状态处理事件
		 */
		mainAction.main.pool.execute(new Runnable() {
			private Park park;

			@Override
			public void run() {
				// AGV车号
				int agvId = recData[NO_BIT];
				// 电池余量
				int battery = recData[BATTERY_BIT];
				// AGV的负载状况
				int loadState = recData[LOAD_BIT];
				// 获取地图X座标
				int mapX = CommandUtil.getMapX4Data(recData);
				Double pointLon = Double.valueOf(mapX);// 纬度（横坐标）
				// 获取地图Y座标
				int mapY = CommandUtil.getMapY4Data(recData);
				Double pointLat = Double.valueOf(mapY);// 经度（纵坐标）
				// 执行码
				int reply = 0;
				String dataStr = HexUtil.byte2HexStr(recData);
				if (!dataStr.substring(0, 2).equals("A1")) {
					return;
				}
				String inputTime = DateUtil.getTimeDate(new Date());
				StringBuffer isb = new StringBuffer(convertData(recData) + "[X座标：" + mapX + "][Y座标：" + mapY + "]");
				Guidepost gp = GuidepostBean.contrast(mainAction.main.guidepostMap, mapX, mapY,
						AgvDispatchAction.RADIUS);// 判断当前座标是否在某个站点的半径范围内（路标，x坐标，y坐标，半径为30）
				if (gp != null) {
					isb.append("[标号：" + gp.getNum() + "]");
				}
				mainAction.main.saveInputLog(5000, dataStr.substring(0, 2), dataStr, isb.toString(), "AGV", agvId + "",
						inputTime);

				Agv agv = mainAction.main.agvMap.get(agvId);
				if (agv != null) {
					String loadHex = HexUtil.encodeHEX(loadState);
					LoadState ls = LoadState.getLoadStateByHex(loadHex);
					// agv状态(数据)
					int state = recData[STATE_BIT];
					boolean lastFlag = false;
					int dcq = agv.getDupCommandQty();
					if (agv.getLastData().equals(dataStr) && dcq < 20) {
						lastFlag = true;
						dcq = dcq + 1;
						agv.setDupCommandQty(dcq);
					} else {
						if (!agv.getLastData().equals(dataStr)) {
							agv.setDupCommandQty(0);
						}
					}
					LimitArea la = getLimitAreaByCoordinate(mapX, mapY);
					if (la != null) {
						agv.setStep(la.getStep());
					}
					agv.setLoadState(ls.getCode());
					agv.setBattery(battery);
					agv.setLastData(dataStr);
					agv.setLastReceiveTime(new Date());
					if (gp != null) {
						agv.setLastPoint(gp.getNum());
					}
					agv.setLastTime(DateUtil.getTimeDate(new Date()));
					agv.setLastX(agv.getCurrentX());
					agv.setLastY(agv.getCurrentY());
					agv.setCurrentX(mapX);
					agv.setCurrentY(mapY);
					// 更新Agv的状态
					if (lastFlag && agv.getState() == AgvState.TZ.getCode()) {
						logger.info("已经接收过相同的数据:" + dataStr);
					} else {
						setAgvState(agvId, state, gp);
					}
					// logger.info("AGV:" + agv.getId() + ",负载情况：" + agv.getLoadState() + "," +
					// LoadState.getValueByCode(agv.getLoadState()));
					AgvState agvState = AgvState.getAgvStateByCode(state);
					park = null;
					try {
						switch (agvState) {
						// 行驶:该地标信息为目的地
						case XS:
							agv.setState(state);
							mainAction.main.insertPaths(mapX, mapY);
							if (reply == 0) {
//								List<FreeArea> freeAreaList = getFreeAreaByCoordinate(pointLon, pointLat);
//								if(freeAreaList.size() > 0){
//									//只要行驶在自由区则检查是否释放了机台
//									for(Map.Entry<String, Station> m:mainAction.main.stationMap.entrySet()){
//										if(m.getValue().joinAgvId == agv.getId()){
//											Station s = m.getValue();
//											s.setJoinAgvId(0);
//											mainAction.main.stationMap.put(s.getName(), s);
//										}
//									}
//								}
							}
							// 行驶时判断座标是否离开泊位的范围
							if (agv.getParkId() > 0) {
								Park p = mainAction.main.parkMap.get(agv.getParkId());
								int gnum = p.getDot();
								Guidepost g = mainAction.getGuidepostByNum(gnum);
								double distance = RegionUtil.distance(g.getMapX(), g.getMapY(), mapX, mapY);
								logger.info("Agv:" + agv.getId() + "距离站点中心：" + distance + "厘米");
								if (distance > 300.0) {// 距离大于300厘米释放工位
									agv.setParkId(0);
									agv.setParkName("");
								}
							}
							for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
								Park pp = mp.getValue();
								if (pp.getAgvId() == agv.getId()) {
									int gnum = pp.getDot();
									Guidepost g = mainAction.getGuidepostByNum(gnum);
									double distance = RegionUtil.distance(g.getMapX(), g.getMapY(), mapX, mapY);
									logger.info("Agv:" + agv.getId() + "距离站点中心：" + distance + "厘米");
									if (distance > 300.0) {// 距离大于300厘米释放工位
										pp.setAgvId(0);
										mainAction.main.parkMap.put(pp.getId(), pp);
									}
								}
							}
							dispatchAgv(agvId, pointLon, pointLat);
							break;
						// 到达:该地标信息为当前站点
						case DD:
							if (reply == 0) {
								if (gp == null) {
									String msg = "AGV:" + agv.getId() + "到达座标X:" + mapX + ",Y:" + mapY + "不是正常地标！！！";
									logger.info(msg);
									mainAction.main.sendMsgByWs(agv.getId() + "", msg);
								} else {
									agvParking(agv, gp);
									park = mainAction.getParkByDot(gp.getNum());
									if (park != null) {
										if (park.getType() == 2 && agv.getBeginChargeTime() == null) {
											agv.setBeginChargeTime(new Date());
										} // 判断par的地标是否等于2（充电桩）并且 充电时间是否为空，为空就重新new一个充电时间。
									}
									if (gp.getType() == GpType.XZD.getCode() || gp.getType() == GpType.CD.getCode()
											|| gp.getType() == GpType.SFJG.getCode()
											|| gp.getType() == GpType.GW.getCode()) {
										// 释放交管
										clearControlArea(agv);
									} // 判断路标类型（gp.getType()）和地标类型（GpType.CD.getCode()）充电是否相等，或者跟释放交管GpType.SFJG.getCode()相等，相等就释放AGV占用区域的所有交管区。
									nextPath(agv, gp);
								}
							}
							break;
						// 对接工位可传输
						case KCS:
							if (gp == null) {
								String msg = "AGV:" + agv.getId() + "可传输，座标X:" + mapX + ",Y:" + mapY + "不是正常工位！！！";
								logger.info(msg);
								mainAction.main.sendMsgByWs(agv.getId() + "", msg);
							} else {
								agvJoin(agv, gp);
								if (gp.getType() == GpType.CD.getCode() || gp.getType() == GpType.SFJG.getCode()
										|| gp.getType() == GpType.GW.getCode()) {
									// 释放交管
									clearControlArea(agv);
								}
							}
							break;
						// 充电
						case CD:
							// 充电释放交管区
//							Date nowDate = new Date();
//							long nowTimes = nowDate.getTime();
//							long chargedStartTimes = agv.getChargerTimes().getTime();
//							long endTimes = (nowTimes - chargedStartTimes) / 1000;
//							// 如果充电桩充电大于设定时间则通知IGV停止充电，退出机台
//							if (endTimes > mainAction.main.chargeDuration) {
//								joinComplete(agvId);
//								return;
//							} else {
//								int i = (int) (mainAction.main.chargeDuration - endTimes);
//								String msg = "IGV充电计时未到，等待：充电倒计时:" + i;
//								mainAction.main.sendMsgByWs(agvId + "", msg);
//							}
							clearControlArea(agv);
							if (agv.getCtrlCommand() != null) {
								mainAction.main.sendDataToAgv(agv.getCtrlCommand(), agv.getCtrlNote(),
										agv.getCtrlState());
							}
							// 清空执行多段线的相关字段
							agv.setIsMultiPath(0);
							agv.setStartPoint(0);
							agv.setEndPoint(0);
							break;
						// 交管
						case JG:
							if (reply == 0) {
								List<ControlArea> controlAreaList = getControlAreaByCoordinate(pointLon, pointLat);
								boolean isTrafficFlag = false;
								if (controlAreaList.size() > 0) {// 如果AGV在非交管区域进入了交管，则向其发送启动指令
									for (ControlArea ca : controlAreaList) {
										if (ca.getRunAgvList().size() > 0) {
											isTrafficFlag = true;
										}
									}
								}
								if (isTrafficFlag) {
									// 更新AGV当前位置与基点的位置
									boolean runFlag = true;
									// 如果
									for (ControlArea ca : controlAreaList) {
										for (ControlRunAgv cagv : ca.getRunAgvList()) {
											if (cagv.getAgvId() != agv.getId()) {
												runFlag = false;
											}
										}
										double distance = RegionUtil.distance(ca.getBaseX(), ca.getBaseY(), pointLon,
												pointLat);
										for (TrafficWait tw : mainAction.main.waitAgvList) {
											if (tw.getAgvId() == agv.getId() && ca.getId() == tw.caId) {
												tw.setDistance(distance);
											}
										}
										String msg = "当前交管区行驶[" + ca.getRunAgvId() + "]号IGV";
										mainAction.main.sendMsgByWs(agv.getId() + "", msg);
									}
									if (runFlag) {
										// 启动AGV
										int startOrStop = 2;// 启动
										byte[] data = CommandUtil.startOrStop(agvId, startOrStop);
										String note = "AGV没有收到启动指令，再次启动AGV！！！";
										mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());
									}
								} else {
									// 启动AGV
									int startOrStop = 2;// 启动
									byte[] data = CommandUtil.startOrStop(agvId, startOrStop);
									String note = "AGV没有收到启动指令，再次启动AGV！！！";
									mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());
								}
							}
							break;
						// 停止
						case TZ:
							if (lastFlag) {
								logger.info("++++++++++已经收到过Agv" + agv.getId() + "的相同数据，不处理!!+++++++++++++");
							} else {
								// 调度不需要介入控制
								agv.setState(state);
								agv.setCtrlState(state);
								agv.setBeginChargeTime(new Date());// 开始充电时间
							}
							break;
						// 上、下层传出完成,向对应机台发送离开申请指令
						case SCCW:
							if (gp == null) {
								return;
							}
							park = mainAction.getParkByDot(gp.getNum());
							Station station = mainAction.getStationByName(park.getStationName());

							if (park.getStep() == Step.ALD.getCode()) {
								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向ALD上料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if ((station.getIsWait() == 0 || station.getIsWait() == 3)
										&& agv.getLoadState() == LoadState.KK.getCode()) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向ALD上料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									joinComplete(agvId);
								}
							}

							if (park.getStep() == Step.PEB.getCode() || park.getStep() == Step.PEZ.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向PE上料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() == 3 && agv.getLoadState() == LoadState.KK.getCode()) {
									// 请求离开
									Thread.sleep(100);
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向PE下料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									joinComplete(agvId);
								}
							}

							if (park.getStep() == Step.ZRS.getCode()) {
								if (station.getIsWait() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "010200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向制绒上料机台发送进料离开信号";
									mainAction.main.sendDataToParkWithLocalPort(mdata, park, note);
								} else if (station.getIsWait() == 3 && agv.getLoadState() == LoadState.KK.getCode()) {
									String hexStr = station.getSname() + "010000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向制绒上料机台发送进料离开信号";
									mainAction.main.sendDataToParkWithLocalPort(mdata, park, note);
									joinComplete(agvId);

								}
							}
							if (park.getStep() == Step.JPS.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向扩散机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() == 3) {
									// 清零复位
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向扩散机台发送进料清零信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 3 && station.getIsWait2() != 2
										&& station.getControlState() == 1 && station.getOutQuantity() == 10
										&& agv.getLoadState() == LoadState.KK.getCode()) {
									// AGV到位后先给机台发出料到位信号
									String hexStr = station.getSname() + "000000010000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向扩散机台发送出料到位信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() == 2 && (agv.getLoadState() == LoadState.KK.getCode()
										|| agv.getLoadState() == LoadState.KN.getCode())) {
									// 向AGV发送上层传入指令
									byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
									String note = "向AGV发送下传入传输指令";
									mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,
								} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.KM.getCode()) {
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 2 && agv.getLoadState() == LoadState.KM.getCode()) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									joinComplete(agvId);
								}
							} else if (park.getStep() == Step.SE.getCode() || park.getStep() == Step.SW.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() != 2 && station.getOutQuantity() == 10
										&& agv.getLoadState() == LoadState.KK.getCode()) {
									// AGV到位后先给机台发出料到位信号
									String hexStr = station.getSname() + "000000010000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送出料到位信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() == 2 && (agv.getLoadState() == LoadState.KK.getCode()
										|| agv.getLoadState() == LoadState.KN.getCode())) {
									// 向AGV发送上层传入指令
									byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
									String note = "向AGV发送下传入传输指令";
									mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,
								} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.KM.getCode()) {
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 2 && agv.getLoadState() == LoadState.KM.getCode()) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									joinComplete(agvId);
								}
							} else if (park.getStep() == Step.HYS.getCode()) {
								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向后氧上料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() != 2 && station.getOutQuantity() == 10
										&& agv.getLoadState() == LoadState.KK.getCode()) {
									// AGV到位后先给机台发出料到位信号
									String hexStr = station.getSname() + "000000010000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向后氧上料机台发送出料到位信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() == 2 && (agv.getLoadState() == LoadState.KK.getCode()
										|| agv.getLoadState() == LoadState.KN.getCode())) {
									// 向AGV发送上层传入指令
									byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
									String note = "向AGV发送下传入传输指令";
									mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,
								} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.KM.getCode()) {
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 2 && agv.getLoadState() == LoadState.KM.getCode()) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									if (isReturnStation4Step(agv, Step.JPFK.getCode())) {
										joinComplete(agvId);
									}
								}
							}
							break;
						case XCCW:
							if (gp == null) {
								return;
							}
							park = mainAction.getParkByDot(gp.getNum());
							station = mainAction.getStationByName(park.getStationName());
							if (park.getStep() == Step.KSX.getCode() || park.getStep() == Step.KSS.getCode()
									|| park.getStep() == Step.HYX.getCode() || park.getStep() == Step.QY.getCode()) {
								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向扩散机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getOutQuantity() == 10 && station.getIsWait2() != 2
										&& station.getIsWait2() != 4 && station.getIsWait() != 4
										&& agv.getLoadState() == LoadState.KK.getCode()) {
									// 请求机台出料
									String hexStr = station.getSname() + "000000010000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向扩散机台发送出料对接信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() == 2 && (agv.getLoadState() == LoadState.KK.getCode()
										|| agv.getLoadState() == LoadState.NK.getCode())) {
									// 向AGV发送上层传入指令
									byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
									String note = "向AGV发送上传入传输指令";
									mainAction.main.sendDataToAgv(adata, note, AgvState.SCR.getCode());
								} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MK.getCode()) {
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向扩散机台发送出料对接信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 2 && agv.getLoadState() == LoadState.MK.getCode()) {
									// 请求离开
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向扩散机台发送进料清零信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									joinComplete(agvId);
								}
							} else if (park.getStep() == Step.JPFK.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait() == 2) {
									String hexStr = station.getSname() + "000200000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛返空机台发送出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() == 3) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛下返空机台发送出料清零信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 3 && agv.getLoadState() == LoadState.KK.getCode()) {
									if (isReturnStation4Step(agv, Step.JPX.getCode())) {
										joinComplete(agvId);
									}
								}
							}
							break;

						// 上、下层传入中，向对应机台发送到位指令
						case XCC:
						case SCR:
						case XCR:
							park = mainAction.getParkByDot(gp.getNum());
							if (park == null) {
								logger.info("当前没有在泊位上【到达】！！！");
							} else {
								station = mainAction.getStationByName(park.getStationName());
//								if (park.getStep() == Step.SE.getCode()) {
//									load4se(agv, park);
//								}
//								if (park.getStep() == Step.ZRX.getCode()) {
//									load4zrx(agv, park);
//								}
							}
							break;
						// 上、下层传入完成,向AGV下发传出指令
						case SCRW:
							if (gp == null) {
								return;
							}
							park = mainAction.getParkByDot(gp.getNum());
							station = mainAction.getStationByName(park.getStationName());
							if (park.getStep() == Step.ALDX.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait2() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000000020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向ALD下料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getOutLeftStop() == 1 && station.getOutRightStop() == 1
										&& station.getIsWait2() != 2 && agv.getLoadState() == LoadState.MK.getCode()) {
									// 请求离开
									String hexStr = station.getSname() + "0000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向ALD下料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									joinComplete(agvId);
								}
							}

							if (park.getStep() == Step.PEBX.getCode() || park.getStep() == Step.PEZX.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait2() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000000020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向PE下料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if ((station.getIsWait2() == 3)
										&& agv.getLoadState() == LoadState.MK.getCode()) {
									// 请求离开
									Thread.sleep(100);
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向PE下料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									joinComplete(agvId);
								}
							}

							if (park.getStep() == Step.KSX.getCode() || park.getStep() == Step.KSS.getCode()
									|| park.getStep() == Step.HYX.getCode() || park.getStep() == Step.QY.getCode()) {
								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait2() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "000000020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = station.getName() + "向下料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if ((station.getIsWait2() != 2 || station.getOutQuantity() != 10)
										&& agv.getLoadState() == LoadState.MK.getCode()) {
									// 请求离开
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = station.getName() + "向下料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									joinComplete(agvId);
								} else if (station.getIsWait() != 2 && station.getInQuantity() == 0
										&& agv.getLoadState() == LoadState.MM.getCode()) {
									// 请求离开
									String hexStr = station.getSname() + "000100000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = station.getName() + "向下料机台发送进料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MM.getCode()) {
									// 向AGV发送下层传出指令
									byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCC.getCode());
									String note = "向AGV发送下层传出指令";
									mainAction.main.sendDataToAgv(adata, note, AgvState.XCC.getCode());// ctrlState,1、上出下入
								}
							}
							if (park.getStep() == Step.JPX.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，清检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getControlState() != 1) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait2() == 2) {
									String hexStr = station.getSname() + "000000020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛下机台发送出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() == 3) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛下机台发送出料清零信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 3 && agv.getLoadState() == LoadState.MK.getCode()) {
									if (isReturnStation(agv, Step.HYS.getCode())) {
										joinComplete(agvId);
									}
								}
							}
							break;
						case XCRW:
							if (gp == null) {
								return;
							}
							park = mainAction.getParkByDot(gp.getNum());
							station = mainAction.getStationByName(park.getStationName());
							if (park.getStep() == Step.ZRX.getCode()) {
								if (station.getIsWait2() == 2) {
									// 请求离开
									String hexStr = station.getSname() + "010002000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向制绒下料机台发送进料离开信号";
									mainAction.main.sendDataToParkWithLocalPort(mdata, park, note);
								} else if (station.getIsWait2() == 3 && agv.getLoadState() == LoadState.KM.getCode()) {
									// 请求离开
									String hexStr = station.getSname() + "010000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向制绒下料机台发送进料离开信号";
									mainAction.main.sendDataToParkWithLocalPort(mdata, park, note);
									joinComplete(agvId);
								}
							}
							if (park.getStep() == Step.JPS.getCode()) {
								if (station.getControlState() == 2) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait2() == 2) {
									String hexStr = station.getSname() + "000000020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛机台发送出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() == 3) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛机台发送出料清零信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() != 3 && agv.getLoadState() == LoadState.KM.getCode()) {
									joinComplete(agvId);
								} else if (station.getIsWait() == 1 && agv.getLoadState() == LoadState.MM.getCode()
										&& station.getControlState() == 1) {
									// AGV到位后先给机台发送到位信号
									String hexStr = station.getSname() + "000100000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛机台发送进料到位信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MM.getCode()) {
									// 向AGV发送下层传出指令
									byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
									String note = "向AGV发送上层传出指令";
									mainAction.main.sendDataToAgv(adata, note, AgvState.SCC.getCode());
								}
							} else if (park.getStep() == Step.SE.getCode() || park.getStep() == Step.SW.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait2() == 2) {
									String hexStr = station.getSname() + "000000020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() != 2 && agv.getLoadState() == LoadState.KM.getCode()) {
									joinComplete(agvId);
								} else if (station.getIsWait() != 2 && agv.getLoadState() == LoadState.MM.getCode()) {
									// AGV到位后先给机台发送到位信号
									String hexStr = station.getSname() + "000100000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛机台发送进料到位信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MM.getCode()) {
									// 向AGV发送下层传出指令
									byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
									String note = "向AGV发送上层传出指令";
									mainAction.main.sendDataToAgv(adata, note, AgvState.SCC.getCode());
								}
							} else if (park.getStep() == Step.HYS.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait2() == 2) {
									String hexStr = station.getSname() + "000000020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向后氧上料机台发送出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait2() != 2 && agv.getLoadState() == LoadState.KM.getCode()) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向后氧上料机台发送出料清零信号";
									mainAction.main.sendDataToPark(mdata, park, note);
									if (isReturnStation(agv, Step.JPFK.getCode())) {
										joinComplete(agvId);
									}
								} else if (station.getIsWait() != 2 && agv.getLoadState() == LoadState.MM.getCode()) {
									// AGV到位后先给机台发送到位信号
									String hexStr = station.getSname() + "000100000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛机台发送进料到位信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MM.getCode()) {
									// 向AGV发送下层传出指令
									byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
									String note = "向AGV发送上层传出指令";
									mainAction.main.sendDataToAgv(adata, note, AgvState.SCC.getCode());
								}
							}
							break;
						case SCXR:

							break;
						// 上出下入完成
						case SCXRW:
							if (gp == null) {
								return;
							}
							park = mainAction.getParkByDot(gp.getNum());
							station = mainAction.getStationByName(park.getStationName());
							if (park.getStep() == Step.SE.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait() == 2 && station.getIsWait2() == 2) {
									String hexStr = station.getSname() + "000200020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向SE机台发送进料/出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 2 && station.getIsWait2() != 2
										&& agv.getLoadState() == LoadState.KM.getCode()) {
									joinComplete(agvId);
								}
							}
							if (park.getStep() == Step.JPS.getCode()) {

								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getControlState() != 1) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}

								if (station.getIsWait() == 2 || station.getIsWait2() == 2) {
									String hexStr = station.getSname() + "000200020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛机台发送进料/出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() == 3 || station.getIsWait2() == 3) {
									String hexStr = station.getSname() + "000000000000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向碱抛机台发送进料/出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 3 && station.getIsWait2() != 3
										&& agv.getLoadState() == LoadState.KM.getCode()) {
									joinComplete(agvId);
								}
							}
							if (park.getStep() == Step.HYS.getCode()) {
								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait() == 2 || station.getIsWait2() == 2) {
									String hexStr = station.getSname() + "000200020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向后氧上料机台发送进料/出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 3 && station.getIsWait2() != 3
										&& agv.getLoadState() == LoadState.KM.getCode()) {
									if (isReturnStation(agv, Step.JPFK.getCode())) {
										joinComplete(agvId);
									}
								}
							}
							break;
						case SRXC:
							break;
						// 上入下出完成
						case SRXCW:
							if (gp == null) {
								return;
							}
							park = mainAction.getParkByDot(gp.getNum());
							station = mainAction.getStationByName(park.getStationName());
							if (park.getStep() == Step.KSX.getCode() || park.getStep() == Step.QY.getCode()
									|| park.getStep() == Step.KSS.getCode() || park.getStep() == Step.HYX.getCode()) {
								if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
									String msg = "机台异常，请检查机台！！";
									mainAction.main.sendMsgByWs(agvId + "", msg);
									return;
								}
								if (station.getIsWait() == 2 || station.getIsWait2() == 2) {
									String hexStr = station.getSname() + "000200020000000000";
									byte[] mdata = HexUtil.hexToByte(hexStr);
									String note = "向扩散/前氧机台发送进料/出料离开信号";
									mainAction.main.sendDataToPark(mdata, park, note);
								} else if (station.getIsWait() != 2 && station.getIsWait2() != 2
										&& agv.getLoadState() == LoadState.MK.getCode()) {
									joinComplete(agvId);
								}
							}

							break;
						// 下左传出完成
						case XZCW:
							// 直接让AGV退回主路
							joinComplete(agv.getId());
							break;
						// 下左传入完成
						case XZRW:
							// 直接让AGV退回主路
							break;
						default:
							break;
						}
						// 任何状态都需要检查座标在不在交管区里，则否把交管区释放掉
						releaseControlArea(agv, mapX, mapY);
//						//更新AGV临时保存数据
//						updateTempAgv(agv);
					} catch (Exception e) {
						logger.error("Exception:", e);
					}
				}
			}
		});
	}

	public void nextPath(Agv agv, Guidepost gp) {
		if (agv.getStartPoint() > 0 && agv.getEndPoint() > 0) {// 交管标（多段线路中途点）
			String pathKey = agv.getStartPoint() + "_" + agv.getEndPoint();
			String pathKey2 = agv.getStartPoint() + "—" + agv.getEndPoint();
			Path path = mainAction.main.mapPathMap.get(pathKey);
			if (path == null) {
				path = mainAction.main.mapPathMap.get(pathKey2);
			}
			if (path == null) {
				logger.info("没有获取到对应线路，KEY：" + pathKey);
			} else {
				String[] arr = path.getNodeArr().split(",");
				for (int i = 0; i < arr.length; i++) {
					String s1 = arr[i];
					int j = i + 1;
					if (s1.equals(gp.getNum() + "") && j < arr.length) {
						String s2 = arr[j];
						// 下发下条线路
						mainAction.taskAction.specifyPath4NumOrDot(agv, gp.getNum(), Integer.parseInt(s2), null);
					}
					if (s1.equals(gp.getNum() + "") && j == arr.length) {
						agv.setIsMultiPath(0);
						agv.setStartPoint(0);
						agv.setEndPoint(0);
					}
				}
			}
		}
	}

	/**
	 * IGV到位机台，开始对接流程
	 * 
	 * @param agv
	 * @param gp
	 */
	public void agvJoin(Agv agv, Guidepost gp) {
		// 对接工位
		if (agv.getBattery() < 37) {
			String msg = "电量过低，请联系厂商操作IGV充电！(请确认无掉料风险)";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
			return;
		} else {
			String msg = "";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		if (gp.getType() == GpType.GW.getCode()) {
			Park park = mainAction.getParkByDot(gp.getNum());

			if (park == null) {
				logger.info("获不到对接的泊位！错误地标号：[" + gp.getNum() + "]");
			} else {
				Station station = mainAction.getStationByName(park.getStationName());
				if (station == null || !station.isInitFlag()) {
					return;
				}
				Step step = Step.getStepByCode(park.getStep());
				logger.info("对接工位：" + park.getName() + ",工序：" + step.getCode() + "[" + step.getName() + "]");
				switch (step) {
				case ZRS:
					// 对接制绒上料
					joinPark4zrs(agv, park);
					break;
				case ZRX:
					// 对接制绒下料
					joinPark4zrx(agv, park);
					break;
				case KSX:
					// 对接扩散
					joinPark4ks(agv, park);
					break;
				case SE:
					// 对接激光
					joinPark4se(agv, park);
					break;
				case QY:
					// 对接前氧
					joinPark4qy(agv, park);
					break;
				case JPS:
					// 对接碱抛上料
					joinPark4jp(agv, park);
					break;
				case JPX:
					// 对接碱抛下料
					joinPark4jpx(agv, park);
					break;
				case HYS:
					// 对接后氧上料
					joinPark4hys(agv, park);
					break;
				case JPFK:
					// 对接碱抛返空
					joinPark4jpfk(agv, park);
					break;
				case KSS:
					// 对接扩散上料
					joinPark4ks(agv, park);
					break;
				case HYX:
					// 对接后氧下料
					joinPark4hyx(agv, park);
					break;
				case ALD:
					// 对接ALD上料
					joinPark4ald(agv, park);
					break;
				case ALDX:
					// 对接ALD下料
					joinPark4aldx(agv, park);
					break;
				case PEB:
					// 对接PE背膜上料
					joinPark4pe(agv, park);
					break;
				case PEBX:
					// 对接PE背膜下料
					joinPark4pex(agv, park);
					break;
				case PEZ:
					// 对接PE正膜上料
					joinPark4pe(agv, park);
					break;
				case PEZX:
					// 对接PE正膜下料
					joinPark4pex(agv, park);
					break;
				case SW:
					// 对接丝网
					joinPark4se(agv, park);
					break;
				}

				// 更新AGV的上次对接机台
				if (station != null) {
					agv.setLastJoinStationId(station.getId());
					agv.setLastJoinStationName(station.getName());
					agv.setpGroup(station.getPGroup());
					agv.setpType(station.getPType());
				}
				// 释放交管
				if (station.getIsClear() == 1) {
					clearControlArea(agv);
				}
				// 释放停泊位
				for (Map.Entry<Integer, Park> mp : mainAction.main.parkMap.entrySet()) {
					Park p = mp.getValue();
					if (park.getId() != p.getId() && p.getAgvId() == agv.getId()) {
						p.setAgvId(0);
						mainAction.main.parkMap.put(p.getId(), p);
					}
				}
			}
		}
	}

	/**
	 * 根据工序和线别遍历agv列表，查询对应工序的agv数量
	 * 
	 * @return
	 */
	public Integer getStepAgvQty(int step, int pGroup) {
		int qty = 0;
		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
			Agv a = am.getValue();
			if (a.getStep() == step && a.getpGroup() == pGroup) {
				qty = qty + 1;
			}
		}
		return qty;
	}

	/**
	 * 退出时判定下一道工序机台是否被占用，如果被占用再判定下一道工序待命位是否有空闲
	 * 
	 * @param step
	 * @param pGrounp
	 * @return
	 */
	public boolean isStepsginFlag(int step, int pGroup, Agv agv) {
		boolean isFlag = false;
		List<Park> tempParkList = mainAction.taskAction.getTempPark(Step.ZRX.getCode(), agv.getpGroup());
		Station qStation = getFreeStationByPGroup(Step.ZRX.getCode(), agv);
		boolean isCharge = false;
		if (qStation == null) {
			isCharge = true;
		} else {
			Park pp = mainAction.getParkByOutNum(qStation.getInNum());
			boolean isGo = checkAgvGoal2(pp, agv);
			if (isGo) {
				isFlag = true;
			} else {
				isCharge = true;
			}
		}
		if (isCharge) {
			if (tempParkList.size() > 0) {
				ParkBean.ItemSort(tempParkList);
				for (Park tp : tempParkList) {
					boolean isGo = true;
					if (tp.getType() == 4) {
						isGo = checkAgvGoal(tp);
					} else if (tp.getType() == 2) {
						isGo = checkAgvGoal2(tp, agv);
					}
					if (isGo) {
						isFlag = true;
						break;
					}
				}
			}
		}

		return isFlag;
	}

	/**
	 * 向AGV发送传出指令
	 */
	public void agvUnload(Agv agv, AgvState as) {
		int lastPoint = agv.getLastPoint();
		Park lastPark = mainAction.getParkByDot(lastPoint);
		Station station = mainAction.main.stationMap.get(lastPark.getName());
		if (station.getTransferFlag() == 1) {
			if (as == AgvState.SCRW) {// 上层传入完成
				int type = TransferType.XCC.getCode();
				byte[] data = CommandUtil.transfer(agv.getId(), type);
				String note = "AGV" + agv.getId() + "下层传出";
				mainAction.main.sendDataToAgv(data, note, AgvState.XCC.getCode());// ctrlState,下层传出
			} else if (as == AgvState.XCRW) {// 下层传入完成
				int type = TransferType.SCC.getCode();
				byte[] data = CommandUtil.transfer(agv.getId(), type);
				String note = "AGV" + agv.getId() + "上层传出";
				mainAction.main.sendDataToAgv(data, note, AgvState.SCC.getCode());// ctrlState,上层传出
			}

		}
	}

	/**
	 * 处理和链氧的对接
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4ly(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		/*
		 * station.setJoinAgvId(agv.getId());//
		 * mainAction.main.stationMap.put(station.getName(), station);
		 * if(station.getType() == 3) { List<CacheShelf> cacheList =
		 * mainAction.taskAction.getcacheShelf4Id(station); CacheShelf cacheShelf =
		 * cacheList.get(0); if(cacheShelf != null) { //送料至缓存架 if(cacheShelf.getInFlag()
		 * == 1 && agv.getLoadState() == LoadState.KM.getCode() && agv.getState() ==
		 * AgvState.KCS.getCode()) { byte[] mdata =
		 * HexUtil.hexToByte("0000000001000000"); String note = "向SE缓存机发送传入到位信号";
		 * mainAction.main.sendDataToPark(mdata, park, note);
		 * 
		 * // 向AGV发送下层传出指令 int type = 4;// 下层传出 byte[] adata =
		 * CommandUtil.transfer(agv.getId(), type); note = "向AGV发送下层传出指令";
		 * mainAction.main.sendDataToAgv(adata, note, AgvState.XCC.getCode());//
		 * ctrlState,1、下层传出 }else if(cacheShelf.getOutFlag() == 1 && agv.getLoadState()
		 * == LoadState.KK.getCode() && agv.getState() == AgvState.KCS.getCode()) {
		 * byte[] mdata = HexUtil.hexToByte("0000000000010000"); String note =
		 * "向SE缓存机发送传入到位信号"; mainAction.main.sendDataToPark(mdata, park, note);
		 * 
		 * // 向AGV发送下层传入指令 int type = TransferType.XCR.getCode();// 下层传入 byte[] adata =
		 * CommandUtil.transfer(agv.getId(), type); note = "向AGV发送下层传出指令";
		 * mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());//
		 * ctrlState,1、下层传出 } } return; }//
		 */
		if (station.getIsWait() == 1 && agv.getState() == AgvState.KCS.getCode()
				&& (agv.getLoadState() == LoadState.KM.getCode() || agv.getLoadState() == LoadState.MM.getCode())) {
			byte[] sendData = HexUtil.hexToByte(station.getSname() + "00010000000000");
			String note = "向链氧机台下层发送传出指令";
			mainAction.main.sendDataToPark(sendData, park, note);
		} else if (station.getIsWait() == 2) {// 下层传出指令触发
			int action = TransferType.XCC.getCode();
			byte[] sendData = CommandUtil.transfer(agv.getId(), action);
			String note = "机台允许传输，向igv发送下层传出指令";
			mainAction.main.sendDataToAgv(sendData, note, TransferType.XCC.getCode());
		} else if (station.getIsWait() == 3) {
			byte[] sendData = HexUtil.hexToByte(station.getSname() + "00020000000000");
			String note = "向链氧机台复位指令";
			mainAction.main.sendDataToPark(sendData, park, note);
		} else if (station.getIsWait2() == 1
				&& (agv.getLoadState() == LoadState.KK.getCode() || agv.getLoadState() == LoadState.KM.getCode())) {
			byte[] sendData = HexUtil.hexToByte(station.getSname() + "00000001000000");
			String note = "向链氧机台上层发送传入指令";
			mainAction.main.sendDataToPark(sendData, park, note);
		} else if (station.getIsWait2() == 2) {// 上层传出指令触发
			int action = TransferType.SCR.getCode();
			byte[] sendData = CommandUtil.transfer(agv.getId(), action);
			mainAction.main.sendDataToAgv(sendData, agv.getId() + "发送", TransferType.SCC.getCode());
		} else if (station.getIsWait2() == 3) {
			byte[] sendData = HexUtil.hexToByte(station.getSname() + "00000002000000");
			String note = "向链氧发送离开信号";
			mainAction.main.sendDataToPark(sendData, park, note);
		} else if ((station.getIsWait() == 0 || station.getIsWait2() == 0)
				&& agv.getLoadState() == LoadState.MK.getCode()) {
			joinComplete(agv.getId());
		}
	}

	/**
	 * 制绒上料机对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4zrs(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		// IGV到达工位点后向机台发送传输通知
		if (station.getIsWait() == 1 && station.getControlState() == 1
				&& agv.getLoadState() == LoadState.MK.getCode()) {
			byte[] data = HexUtil.hexToByte(station.getSname() + "01010000000000");
			String note = "向制绒上料机" + station.getName() + "发送数据：" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToParkWithLocalPort(data, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MK.getCode()
				&& station.getControlState() == 1) {
			byte[] data = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
			String note = "向IGV发送上层传输指令:" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToAgv(data, note, TransferType.SCC.getCode());

		}

	}

	/**
	 * ald上料机对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4ald(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
			return;
		}

		// IGV到达工位点后向机台发送传输通知
		if (station.getIsWait() == 1 && station.getInQuantity() == 0) {
			byte[] data = HexUtil.hexToByte(station.getSname() + "000100000000000000");
			String note = "向ALD上料机" + station.getName() + "发送数据：" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToPark(data, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MK.getCode()) {
			byte[] data = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
			String note = "向IGV发送上层传输指令:" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToAgv(data, note, TransferType.SCC.getCode());

		}

	}

	/**
	 * ald上料机对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4pe(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
			return;
		}

		// IGV到达工位点后向机台发送传输通知
		if (station.getIsWait() == 1 && station.getInQuantity() == 0) {
			byte[] data = HexUtil.hexToByte(station.getSname() + "000100000000000000");
			String note = "向ALD上料机" + station.getName() + "发送数据：" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToPark(data, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MK.getCode()) {
			byte[] data = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
			String note = "向IGV发送上层传输指令:" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToAgv(data, note, TransferType.SCC.getCode());

		}

	}

	/**
	 * aldx上料机对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4aldx(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
			return;
		}

		// IGV到达工位点后向机台发送传输通知
		if (station.getIsWait2() == 1 && station.getOutQuantity() == 10) {
			byte[] data = HexUtil.hexToByte(station.getSname() + "000000010000000000");
			String note = "向ALD下料机" + station.getName() + "发送数据：" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToPark(data, park, note);
		} else if (station.getIsWait2() == 2 && station.getOutLeftStop() == 0 && station.getOutRightStop() == 0
				&& (agv.getLoadState() == LoadState.KK.getCode() || agv.getLoadState() == LoadState.NK.getCode())) {
			byte[] data = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向IGV发送上层传输指令:" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToAgv(data, note, TransferType.SCR.getCode());

		}

	}

	/**
	 * aldx上料机对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4pex(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
			return;
		}

		// IGV到达工位点后向机台发送传输通知
		if (station.getIsWait2() != 2 && station.getOutQuantity() == 10) {
			byte[] data = HexUtil.hexToByte(station.getSname() + "000000010000000000");
			String note = "向ALD下料机" + station.getName() + "发送数据：" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToPark(data, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.KK.getCode() || agv.getLoadState() == LoadState.NK.getCode())) {
			byte[] data = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向IGV发送上层传输指令:" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToAgv(data, note, TransferType.SCR.getCode());

		}

	}

	/**
	 * 处理IGV小车到达后的机台对接
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4zrx(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		// IGV到达工位点后向机台发送传输通知
		if (station.getIsWait2() != 2 && station.getOutQuantity() == 10 && station.getControlState() == 1
				&& agv.getLoadState() == LoadState.KK.getCode()) {
			byte[] data = HexUtil.hexToByte(station.getSname() + "01000100000000");
			String note = "向制绒下料机" + station.getName() + "发送数据：" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToParkWithLocalPort(data, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.KK.getCode() || agv.getLoadState() == LoadState.KN.getCode())) {
			byte[] data = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
			String note = "向IGV发送下层传输指令:" + HexUtil.byte2HexStr(data);
			mainAction.main.sendDataToAgv(data, note, TransferType.XCR.getCode());

		}
	}

	/**
	 * 00 01 00 01 00 01 00 00 word1:线别，word2:到达进料口，word3:到达出料口
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4fl(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);
		// 翻篮进料工位
		if (park.getType() == 5 && station.getIsWait() == 1 && agv.getLoadState() == LoadState.KM.getCode()) {
			byte[] recData = { 0, 0, 0, (byte) 1, 0, 0, 0, 0 };
			String note = "翻篮传入到位";
			mainAction.main.sendDataToPark(recData, park, note);
			try {
				Thread.sleep(1000);
			} catch (Exception e) {
				logger.error("延时抛错：", e);
			}
			// 向AGV发达左下传出
			byte[] data = CommandUtil.transfer(agv.getId(), TransferType.XZC.getCode());
			int ctrlState = AgvState.XZC.getCode();// 左下传出
			note = "制绒上料传入";
			mainAction.main.sendDataToAgv(data, note, ctrlState);
		}
		// 翻篮出料工位
		if (park.getType() == 6 && station.getIsWait2() == 1) {
			// 向AGV发达左下传出
			byte[] data = CommandUtil.transfer(agv.getId(), TransferType.XZR.getCode());
			int ctrlState = AgvState.XZR.getCode();// 左下传入
			String note = "制绒上料传入";
			mainAction.main.sendDataToAgv(data, note, ctrlState);

			byte[] recData = { 0, 0, 0, 0, 0, (byte) 1, 0, 0 };
			note = "翻篮传出到位";
			mainAction.main.sendDataToPark(recData, park, note);
		}

	}

	private void load4zrx(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);
		byte[] recData = { (byte) 0, (byte) 1, 0, 0, 0, 0, 0, 0 };
		String note = "制绒上料传入";
		mainAction.main.sendDataToPark(recData, park, note);
	}

	/**
	 * SE对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	public void joinPark4se(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);
//		if (station.getType() == 3) {
//			List<CacheShelf> cacheList = mainAction.taskAction.getcacheShelf4Id(station);
//			CacheShelf cacheShelf = cacheList.get(0);
//			if (cacheShelf != null) {
//				// 送料至缓存架
//				if (cacheShelf.getInFlag() == 1 && agv.getLoadState() == LoadState.KM.getCode()
//						&& agv.getState() == AgvState.KCS.getCode()) {
//					byte[] mdata = HexUtil.hexToByte("0000000100000000");
//					String note = "向SE缓存机发送传入到位信号";
//					mainAction.main.sendDataToPark(mdata, park, note);
//
//					// 向AGV发送下层传出指令
//					int type = 4;// 下层传出
//					byte[] adata = CommandUtil.transfer(agv.getId(), type);
//					note = "向AGV发送下层传出指令";
//					mainAction.main.sendDataToAgv(adata, note, AgvState.XCC.getCode());// ctrlState,1、下层传出
//				} else if (cacheShelf.getOutFlag() == 1 && agv.getLoadState() == LoadState.KK.getCode()
//						&& agv.getState() == AgvState.KCS.getCode()) {
//					byte[] mdata = HexUtil.hexToByte("0000000000010000");
//					String note = "向SE缓存机发送传入到位信号";
//					mainAction.main.sendDataToPark(mdata, park, note);
//
//					// 向AGV发送下层传入指令
//					int type = TransferType.XCR.getCode();// 下层传入
//					byte[] adata = CommandUtil.transfer(agv.getId(), type);
//					note = "向AGV发送下层传出指令";
//					mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,1、下层传出
//				}
//			}
//			return;
//		}

		if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
			return;
		}

		// 进料/出料对接
		if (station.getInQuantity() == 0 && station.getOutQuantity() == 10 && station.getIsWait() != 2
				&& station.getIsWait() != 2 && agv.getLoadState() == LoadState.MK.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向SE机台发送进出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.MK.getCode() || agv.getLoadState() == LoadState.MN.getCode())) {
			// 向AGV发送上出下入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCXR.getCode());
			String note = "向AGV发送上出下入指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCXR.getCode());// ctrlState,1、上出下入
		} else if (station.getInQuantity() == 0 && station.getIsWait() != 2
				&& agv.getLoadState() == LoadState.MK.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100000000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向SE机台发送进料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MK.getCode()) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
			String note = "向AGV发送上层传出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCC.getCode());// ctrlState,1、上出下入
		} else if (station.getOutQuantity() == 10 && station.getIsWait2() != 2
				&& (agv.getLoadState() == LoadState.KK.getCode())) {
			// AGV到位后先给机台发出料到位信号
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向SE机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.KN.getCode() || agv.getLoadState() == LoadState.KK.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
			String note = "向AGV发送下传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,1、上出下入
		} else if (station.getIsWait2() != 2 && agv.getLoadState() == LoadState.MK.getCode()
				&& station.getInQuantity() != 0 && station.getOutQuantity() == 10) {
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向SE上料机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.MN.getCode() || agv.getLoadState() == LoadState.MK.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,1、上出下入
		}

		// 同时进出料对接

	}

	public void joinPark4se2(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);
		if (station.getIsWait2() == 1 && agv.getLoadState() == LoadState.KK.getCode()
				&& (agv.getState() == AgvState.KCS.getCode() || agv.getState() == AgvState.XCCW.getCode())) {
			// 向AGV发送下层传出指令
			int type = 5;// 下层传入
			byte[] adata = CommandUtil.transfer(agv.getId(), type);
			String note = "向AGV发送下层传入指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,1、下层传入
		}
	}

	public void load4se(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);
		if (station.getType() != 3) {
			String hexStr = station.getSname() + "00000000010000";// 传出到位
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向SE机台发送传出到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		}
	}

	/**
	 * 前氧对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4qy(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
			return;
		}
		// 进料/出料对接
		if (station.getInQuantity() == 0 && station.getOutQuantity() == 10 && station.getIsWait() != 2
				&& station.getIsWait2() != 2 && agv.getLoadState() == LoadState.KM.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向前氧机台发送进出料同时进行信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && station.getIsWait2() == 2) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SRXC.getCode());
			String note = "向AGV发送下入上出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SRXC.getCode());// ctrlState,1、上出下入
		} else if (station.getInQuantity() == 0 && station.getIsWait() != 2 && station.getIsWait2() != 2
				&& (agv.getLoadState() == LoadState.KM.getCode() || agv.getLoadState() == LoadState.NM.getCode())) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100000000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向前氧机台发送进料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.KM.getCode()) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCC.getCode());
			String note = "向AGV发送下层传出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCC.getCode());// ctrlState,1、上出下入
		} else if (station.getOutQuantity() == 10 && station.getIsWait2() != 2
				&& (agv.getLoadState() == LoadState.KK.getCode())) {
			// AGV到位后先给机台发出料到位信号
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向前氧机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2 && agv.getLoadState() == LoadState.KK.getCode()) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCR.getCode());// ctrlState,1、上出下入
		} else if (station.getIsWait2() != 2 && agv.getLoadState() == LoadState.KM.getCode()
				&& station.getInQuantity() != 0 && station.getOutQuantity() == 10) {
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向前氧机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.NM.getCode() || agv.getLoadState() == LoadState.KM.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCR.getCode());// ctrlState,1、上出下入
		}

	}

	/**
	 * 碱抛对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4jp(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		/**
		 * 如果异常，直接退出
		 */
		if (station.getControlState() != 1) {
			return;
		}
		// 进料/出料对接
		if (station.getInQuantity() == 0 && station.getOutQuantity() == 10 && station.getIsWait() != 2
				&& station.getIsWait() != 2 && agv.getLoadState() == LoadState.MK.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向碱抛机台发送进出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.MK.getCode() || agv.getLoadState() == LoadState.MN.getCode())) {
			// 向AGV发送上出下入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCXR.getCode());
			String note = "向AGV发送上出下入指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCXR.getCode());// ctrlState,1、上出下入
		} else if (station.getIsWait() == 1 && station.getInQuantity() == 0
				&& agv.getLoadState() == LoadState.MK.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100000000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向碱抛机台发送进料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MK.getCode()) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
			String note = "向AGV发送上层传出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCC.getCode());// ctrlState,1、上出下入
		} else if (station.getOutQuantity() == 10 && station.getIsWait2() != 2
				&& (agv.getLoadState() == LoadState.KK.getCode())) {
			// AGV到位后先给机台发出料到位信号
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向碱抛机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2 && agv.getLoadState() == LoadState.KK.getCode()) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
			String note = "向AGV发送下传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,1、上出下入
		} else if (station.getIsWait2() != 2 && agv.getLoadState() == LoadState.MK.getCode()
				&& station.getInQuantity() != 0 && station.getOutQuantity() == 10) {
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向碱抛上料机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.MN.getCode() || agv.getLoadState() == LoadState.MK.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
			String note = "向AGV发送下传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,1、上出下入
		}
	}

	/**
	 * 碱抛下料对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4jpx(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		if (station.getControlState() != 1) {
			return;
		}

		if (station.getOutQuantity() == 10 && station.getIsWait2() != 2
				&& (agv.getLoadState() == LoadState.KK.getCode())) {
			// AGV到位后先给机台发出料到位信号
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向碱抛返空机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.NK.getCode() || agv.getLoadState() == LoadState.KK.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCR.getCode());// ctrlState,1、上出下入
		}
	}

	/**
	 * 扩散对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4ks(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		// 进料/出料对接
		// 同时进出料
		// 异常直接退出
		if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
			return;
		}

		if (station.getInQuantity() == 0 && station.getOutQuantity() == 10 && station.getIsWait() != 2
				&& station.getIsWait2() != 2 && agv.getLoadState() == LoadState.KM.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向扩散机台发送进出料同时进行信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && station.getIsWait2() == 2) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SRXC.getCode());
			String note = "向AGV发送下入上出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SRXC.getCode());// ctrlState,1、上出下入
		} else if (station.getInQuantity() == 0 && station.getIsWait() != 2 && station.getIsWait2() != 2
				&& agv.getLoadState() == LoadState.KM.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100000000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向扩散机台发送进料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.KM.getCode()) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCC.getCode());
			String note = "向AGV发送下层传出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCC.getCode());// ctrlState,1、上出下入
		} else if (station.getOutQuantity() == 10 && station.getIsWait2() != 2
				&& (agv.getLoadState() == LoadState.KK.getCode())) {
			// AGV到位后先给机台发出料到位信号
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向扩散机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.NK.getCode() || agv.getLoadState() == LoadState.KK.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCR.getCode());// ctrlState,1、上出下入
		} else if (station.getIsWait() != 2 && station.getIsWait2() != 2 && agv.getLoadState() == LoadState.KM.getCode()
				&& station.getInQuantity() != 0 && station.getOutQuantity() == 10) {
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向扩散机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.NM.getCode() || agv.getLoadState() == LoadState.KM.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCR.getCode());// ctrlState,1、上出下入
		}
	}

	/**
	 * 碱抛返空花篮对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4jpfk(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		if (station.getControlState() != 1) {
			return;
		}

		if (station.getInQuantity() == 0 && station.getIsWait() == 1
				&& (agv.getLoadState() == LoadState.KM.getCode())) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100000000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向扩散机台发送进料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.KM.getCode()) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCC.getCode());
			String note = "向AGV发送下层传出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCC.getCode());// ctrlState,1、上出下入
		}
	}

	/**
	 * 后氧上对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4hys(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);
		// 进料/出料对接
		// 同时进出料
		if (station.getInQuantity() == 0 && station.getOutQuantity() == 10 && station.getIsWait() != 2
				&& station.getIsWait2() != 2 && agv.getLoadState() == LoadState.MK.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向后氧机台发送进出料同时进行信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && station.getIsWait2() == 2) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCXR.getCode());
			String note = "向AGV发送下入上出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCXR.getCode());// ctrlState,1、上出下入
		} else if (station.getInQuantity() == 0 && station.getIsWait() != 2 && station.getIsWait2() != 2
				&& agv.getLoadState() == LoadState.MK.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100000000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向后氧机台发送进料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.MK.getCode()) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCC.getCode());
			String note = "向AGV发送下层传出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCC.getCode());// ctrlState,1、上出下入
		} else if (station.getOutQuantity() == 10 && station.getIsWait2() != 2
				&& (agv.getLoadState() == LoadState.KK.getCode())) {
			// AGV到位后先给机台发出料到位信号
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向扩散机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.KN.getCode() || agv.getLoadState() == LoadState.KK.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,1、上出下入
		} else if (station.getIsWait() != 2 && station.getIsWait2() != 2 && agv.getLoadState() == LoadState.MK.getCode()
				&& station.getInQuantity() != 0 && station.getOutQuantity() == 10) {
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向扩散机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.MN.getCode() || agv.getLoadState() == LoadState.MK.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCR.getCode());// ctrlState,1、上出下入
		}

	}

	/**
	 * 后氧下料对接处理
	 * 
	 * @param agv
	 * @param park
	 */
	private void joinPark4hyx(Agv agv, Park park) {
		Station station = mainAction.getStationByName(park.getStationName());
		station.setJoinAgvId(agv.getId());
		mainAction.main.stationMap.put(station.getName(), station);

		if (station.getIsWait() == 4 || station.getIsWait2() == 4) {
			return;
		}
		// 进料/出料对接
		// 同时进出料
		if (station.getInQuantity() == 0 && station.getOutQuantity() == 10 && station.getIsWait() != 2
				&& station.getIsWait2() != 2 && agv.getLoadState() == LoadState.KM.getCode()) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向后氧下料机台发送进出料同时进行信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && station.getIsWait2() == 2) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SRXC.getCode());
			String note = "向AGV发送下入上出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SRXC.getCode());// ctrlState,1、上出下入
		} else if (station.getInQuantity() == 0 && station.getIsWait() != 2
				&& (agv.getLoadState() == LoadState.KM.getCode() || agv.getLoadState() == LoadState.NM.getCode())) {
			// AGV到位后先给机台发送到位信号
			String hexStr = station.getSname() + "000100000000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向后氧机台发送进料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait() == 2 && agv.getLoadState() == LoadState.KM.getCode()) {
			// 向AGV发送下层传出指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.XCC.getCode());
			String note = "向AGV发送下层传出指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.XCC.getCode());// ctrlState,1、上出下入
		} else if (station.getOutQuantity() == 10 && station.getIsWait2() != 2
				&& (agv.getLoadState() == LoadState.KK.getCode())) {
			// AGV到位后先给机台发出料到位信号
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向后氧机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.NK.getCode() || agv.getLoadState() == LoadState.KK.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCR.getCode());// ctrlState,1、上出下入
		} else if (station.getIsWait2() != 2 && agv.getLoadState() == LoadState.KM.getCode()
				&& station.getInQuantity() != 0 && station.getOutQuantity() == 10) {
			String hexStr = station.getSname() + "000000010000000000";
			byte[] mdata = HexUtil.hexToByte(hexStr);
			String note = "向后氧下料机台发送出料到位信号";
			mainAction.main.sendDataToPark(mdata, park, note);
		} else if (station.getIsWait2() == 2
				&& (agv.getLoadState() == LoadState.NM.getCode() || agv.getLoadState() == LoadState.KM.getCode())) {
			// 向AGV发送上层传入指令
			byte[] adata = CommandUtil.transfer(agv.getId(), TransferType.SCR.getCode());
			String note = "向AGV发送上传入传输指令";
			mainAction.main.sendDataToAgv(adata, note, AgvState.SCR.getCode());// ctrlState,1、上出下入
		}
	}

	/**
	 * 制绒上料
	 * 
	 * @param agv
	 * @param park
	 */
	private void toNextPark4zrs(Agv agv, Park park) {
		Station qStation = null;

		// 上空下空的处理
		if (agv.getLoadState() == LoadState.MK.getCode()) {
			/**
			 * 1、先找相邻工位是否需要接料； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getRequireStation4KS(Step.ZRS.getCode(), agv);
		}
		Guidepost xzNum = mainAction.getGuidepostByStep2(Step.ZRX.getCode(), park.getXzdNumItem());
		if (xzNum != null) {
			mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
		} else {
			String msg = "制绒对应下料机已被车占用";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
	}

	/**
	 * 制绒下料对接完成，到扩散的对应工位
	 * 
	 * @param agv
	 * @param park
	 */
	public void toNextPark4zrx(Agv agv, Park park) {
		Station qStation = null;

		// 上空下空的处理
		if (agv.getLoadState() == LoadState.KK.getCode()) {
			/**
			 * 1、先找相邻工位是否需要接料； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getRequireStation4KS(Step.ZRX.getCode(), agv);
		}
		// 上满下空的处理
//		if (agv.getLoadState() == LoadState.KM.getCode()) {
		/**
		 * 1、先找SE工序的对应工位是否空闲； 2、再找空闲的临时泊位停靠；
		 */
		qStation = getFreeStationByOutintitry(Step.KSS.getCode(), agv);
//		}

//		if (qStation == null) {// 没有机台要下料，去旁边的临时位置等待
		List<Park> tempParkList = mainAction.taskAction.getTempPark(Step.KSS.getCode());
		if (tempParkList.size() > 0) {
			ParkBean.ItemSort(tempParkList);
			boolean flag = true;
			int end = 0;
			for (Park tp : tempParkList) {
				boolean isGo = checkAgvGoal2(tp, agv);
				if (isGo) {
					if (tp.getType() == 2) {
						end = tp.getOutNum();
					} else {
						end = tp.getDot();
					}
					mainAction.taskAction.multiPath4z(agv, park.getOutNum(), end);
					flag = false;
					break;
				}
			}
		} else {
			String msg = "充电泊位已被车占用！等待";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
//		} else {// 有机台要下料，过去接料
////			if (agv.getLoadState() == LoadState.KM.getCode()) {
//			Guidepost xzNum = mainAction.getGuidepostByStep2(Step.KSS.getCode(), 0);
//			if (xzNum != null && checkAgvGoal2(xzNum.getNum(), agv)) {
//				mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
//			} else {
//				List<Park> tempParkList = mainAction.taskAction.getTempPark(Step.KSS.getCode());
//				if (tempParkList.size() > 0) {
//					ParkBean.ItemSort(tempParkList);
//					boolean flag = true;
//					int end = 0;
//					for (Park tp : tempParkList) {
//						boolean isGo = checkAgvGoal2(tp, agv);
//						if (isGo) {
//							if (tp.getType() == 2) {
//								end = tp.getOutNum();
//							} else {
//								end = tp.getDot();
//							}
//							mainAction.taskAction.multiPath4z(agv, park.getOutNum(), end);
//							flag = false;
//							break;
//						}
//					}
//				} else {
//					String msg = "扩散对应上料机已被车占用,且该工序无待命点可停";
//					mainAction.main.sendMsgByWs(agv.getId() + "", msg);
//				}
//			}
//		}
//		}
	}

	/**
	 * 离开扩散上料
	 */
	private void toNextPark4kss(Agv agv, Park park) {

		// 上满下空的处理
//		if (agv.getLoadState() == LoadState.MK.getCode()) {
		// 低于指定电量，先去充电够一定时长再继续充电
		if (agv.getBattery() < 60) {
			List<Park> dmParks = mainAction.taskAction.getTempChargerPark4Priority(998, park);
			if (dmParks.size() > 0) {
				for (Park p : dmParks) {
					if (checkAgvGoal2(p, agv)) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), p.getOutNum());
						return;
					}
				}
			}
		}

		// 电量超过65以上可以行走，低于65强制充电
		Guidepost xzNum = mainAction.getGuidepostByStep(Step.ZRS.getCode());
		int goCount = 0;
		for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
			if ((m.getValue().getGoal() == xzNum.getNum() || m.getValue().getLastPoint() == xzNum.getNum())
					&& agv.getId() != m.getValue().getId()) {
				goCount += 1;
			}
		}
		if (xzNum != null) {
			mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
		} else {
			// 当有车辆去往选择点的时候，则去该工序的充电点
			List<Park> dmParks = mainAction.taskAction.getTempChargerPark(998, park);
			if (dmParks.size() > 0) {
				for (Park p : dmParks) {
					if (checkAgvGoal2(p, agv)) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), p.getOutNum());
						return;
					}
				}
			}
			mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
		}

	}

	/**
	 * 扩散退出点处理
	 * 
	 * @param agv
	 * @param park
	 */
	public void toNextPark4ks(Agv agv, Park park) {
		Station qStation = null;

		// 上空下空的处理
		if (agv.getLoadState() == LoadState.KK.getCode()) {
			/**
			 * 1、先找相邻工位是否需要接料； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getRequireStation4KS(Step.KSX.getCode(), agv);
		}
		// 上满下空的处理
		if (agv.getLoadState() == LoadState.MK.getCode()) {
			/**
			 * 1、先找SE工序的对应工位是否空闲； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getFreeStationByOutintitry(Step.SE.getCode(), agv);
		}

		if (qStation == null) {// 没有机台要下料，去旁边的临时位置等待
			List<Park> tempParkList = mainAction.taskAction.getTempPark(Step.SE.getCode());
			int emptyAgvQty = 0;
			for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
				if (am.getValue().getStep() == Step.KSX.getCode()
						&& am.getValue().getLoadState() == LoadState.KK.getCode()) {
					emptyAgvQty = emptyAgvQty + 1;
				}
			}
			if (tempParkList.size() > 0) {
				ParkBean.ItemSort(tempParkList);
				boolean flag = true;
				int end = 0;
				for (Park tp : tempParkList) {
					boolean isGo = checkAgvGoal2(tp, agv);
					if (isGo) {
						if (tp.getType() == 2) {
							end = tp.getOutNum();
						} else {
							end = tp.getDot();
						}
						flag = false;
						break;
					}
				}
				mainAction.taskAction.multiPath4z(agv, park.getOutNum(), end);

			}
		} else {// 有机台要下料，过去接料
			if (agv.getLoadState() == LoadState.MK.getCode()) {
				Guidepost xzNum = mainAction.getGuidepostByStep(Step.SE.getCode());
				if (xzNum != null) {
//					if (checkAgvGoal2(xzNum.getNum(), agv)) {
					mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
//					}
				}
			}
		}
	}

	/**
	 * SE对接完成，退出机台
	 * 
	 * @param agv
	 * @param park
	 */
	private void toNextPark4se(Agv agv, Park park) {
		Station qStation = null;

		// 上空下空的处理
		if (agv.getLoadState() == LoadState.KK.getCode()) {
			/**
			 * 1、先找相邻工位是否需要接料； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getRequireStation4KS(Step.SE.getCode(), agv);
		}
		// 上满下空的处理
		if (agv.getLoadState() == LoadState.KM.getCode()) {
			/**
			 * 1、先找SE工序的对应工位是否空闲； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getFreeStationByOutintitry(Step.QY.getCode(), agv);
		}

		if (qStation == null) {// 没有机台要下料，去旁边的临时位置等待
			List<Park> tempParkList = mainAction.taskAction.getTempPark(Step.QY.getCode());
			if (tempParkList.size() > 0) {
				ParkBean.ItemSort(tempParkList);
				boolean flag = true;
				int end = 0;
				for (Park tp : tempParkList) {
					boolean isGo = checkAgvGoal2(tp, agv);
					if (isGo) {
						if (tp.getType() == 2) {
							end = tp.getOutNum();
						} else {
							end = tp.getDot();
						}
						flag = false;
						break;
					}
				}
				mainAction.taskAction.multiPath4z(agv, park.getOutNum(), end);

			}
		} else {// 有机台要下料，过去接料
			if (agv.getLoadState() == LoadState.KM.getCode()) {
				Guidepost xzNum = mainAction.getGuidepostByStep2(Step.QY.getCode(), park.getXzdNumItem());
				if (xzNum != null) {
					if (checkAgvGoal2(xzNum.getNum(), agv)) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
					}
				}
			}
		}
	}

	private void toNextPark4qy(Agv agv, Park park) {
		Station qStation = null;

		// 上空下空的处理
		if (agv.getLoadState() == LoadState.KK.getCode()) {
			/**
			 * 1、先找相邻工位是否需要接料； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getRequireStation4KS(Step.QY.getCode(), agv);
		}
		// 上满下空的处理
//		if (agv.getLoadState() == LoadState.MK.getCode()) {
		/**
		 * 1、先找SE工序的对应工位是否空闲； 2、再找空闲的临时泊位停靠；
		 */
		qStation = getFreeStationByOutintitry(Step.JPS.getCode(), agv);
//		}

		// 如果电量低于60，则强制去充电桩充电
		if (agv.getBattery() < 60) {
			List<Park> parks = mainAction.taskAction.getTempChargerPark(997, park);
			if (parks.size() > 0) {
				for (Park chPark : parks) {
					if (checkAgvGoal2(chPark, agv)) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), chPark.getOutNum());
						return;
					}
				}
			}
		}
		if (qStation == null) {// 没有机台要下料，去旁边的临时位置等待
			List<Park> tempParkList = mainAction.taskAction.getTempPark(Step.JPS.getCode());
			if (tempParkList.size() > 0) {
				ParkBean.ItemSort(tempParkList);
				boolean flag = true;
				int end = 0;
				for (Park tp : tempParkList) {
					boolean isGo = checkAgvGoal2(tp, agv);
					if (isGo) {
						if (tp.getType() == 2) {
							end = tp.getOutNum();
						} else {
							end = tp.getDot();
						}
						flag = false;
						break;
					}
				}
				mainAction.taskAction.multiPath4z(agv, park.getOutNum(), end);

			}
		} else {// 有机台要下料，过去接料
//			if (agv.getLoadState() == LoadState.MK.getCode()) {
			Guidepost xzNum = mainAction.getGuidepostByStep2(Step.JPS.getCode(), park.getXzdNumItem());
			if (xzNum != null) {
				if (checkAgvGoal2(xzNum.getNum(), agv)) {
					mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
				}
			}
//			}
		}
	}

	private void toNextPark4jps(Agv agv, Park park) {
		Station qStation = null;

		// 上空下空的处理
		if (agv.getLoadState() == LoadState.KK.getCode()) {
			/**
			 * 1、先找相邻工位是否需要接料； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getRequireStation4KS(Step.JPS.getCode(), agv);
		}
		// 上满下空的处理
		if (agv.getLoadState() == LoadState.KM.getCode()) {
			/**
			 * 1、先找SE工序的对应工位是否空闲； 2、再找空闲的临时泊位停靠；
			 */
			qStation = getFreeStationByOutintitry(Step.KSX.getCode(), agv);
		}

		if (qStation == null) {// 没有机台要下料，去旁边的临时位置等待
			List<Park> tempParkList = mainAction.taskAction.getTempPark(Step.KSX.getCode());
			if (tempParkList.size() > 0) {
				ParkBean.ItemSort(tempParkList);
				boolean flag = true;
				int end = 0;
				for (Park tp : tempParkList) {
					boolean isGo = checkAgvGoal2(tp, agv);
					if (isGo) {
						if (tp.getType() == 2) {
							end = tp.getOutNum();
						} else {
							end = tp.getDot();
						}
						flag = false;
						break;
					}
				}
				mainAction.taskAction.multiPath4z(agv, park.getOutNum(), end);

			}
		} else {// 有机台要下料，过去接料
//			if (agv.getLoadState() == LoadState.KM.getCode()) {
			Guidepost xzNum = mainAction.getGuidepostByStep2(Step.KSX.getCode(), 0);
			if (xzNum != null) {
//					if (checkAgvGoal2(xzNum.getNum(), agv)) {
				mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
//					}
//				}
			}
		}
	}

	/**
	 * 更新AGV的状态
	 * 
	 * @param agvId
	 * @param state
	 * @param gdid
	 */
	public void setAgvState(int agvId, int state, Guidepost gp) {
		Agv agv = mainAction.main.agvMap.get(agvId);
		agv.setState(state);
		if (state == AgvState.DD.getCode() && gp != null) {// 系统状态为“到达”
			if (gp != null) {
				if (gp.getAgvState() > 0) {
					agv.setState(gp.getAgvState());
				} else {
					agv.setState(state);
				}

				Park park = mainAction.getParkByDot(gp.getNum());
				if (park != null) {
					agv.setParkId(park.getId());
					agv.setParkName(park.getName());
					agv.setWaitParkTimes(new Date());
					park.setAgvId(agv.getId());
					mainAction.main.parkMap.put(park.getId(), park);
					for (Map.Entry<Integer, Park> pm : mainAction.main.parkMap.entrySet()) {
						if (pm.getValue().getId() != park.getId() && pm.getValue().getAgvId() == agv.getId()) {
							Park p = pm.getValue();
							p.setAgvId(0);
							mainAction.main.parkMap.put(p.getId(), p);
						}
					}
					// 插入进入站点历史
					// String inTime = DateUtil.getTimeDate(new Date());
					// mainAction.main.insertParkLog(park.getId(), park.getName(), agvId, inTime);
				}
			}
		}

		if (state == AgvState.XS.getCode()) {
			// 当AGV行驶时确保清除掉[ctrlCommmand],防止误发指令
			if (agv.getCtrlCommand() != null) {
				agv.setCtrlCommand(null);
			}
			if (agv.getBeginChargeTime() != null) {
				agv.setBeginChargeTime(null);
			}
		}
		agv.setCtrlState(agv.getState());

		if (agv.getLastState() != agv.getState()) {
			String lastStateStr = AgvState.getValueByCode(agv.getLastState());
			String stateStr = AgvState.getValueByCode(agv.getState());
			String timeStr = DateUtil.getTimeDate(new Date());
			StringBuffer sb = new StringBuffer("agv:" + agv.getId() + ",原状态：" + lastStateStr + ",现状态：" + stateStr);
			if (gp != null) {
				String stepStr = Step.getValueByCode(gp.getStep());
				sb.append(",地标号：" + gp.getNum() + ",工序：" + stepStr);
				agv.setLastPoint(gp.getNum());
				/**
				 * 更新目的地标,更新到达地标
				 */
				if ((gp.getType() == GpType.GW.getCode() || gp.getType() == GpType.CD.getCode()
						|| gp.getType() == GpType.LS.getCode())
						&& (agv.getState() == AgvState.DD.getCode() || agv.getState() == AgvState.CD.getCode()
								|| agv.getState() == AgvState.KCS.getCode())) {
					agv.setGoal(gp.getNum());
					// 清空多段线的相关字段
					agv.setIsMultiPath(0);
					agv.setStartPoint(0);
					agv.setEndPoint(0);
				}
			}
			sb.append(",时间：" + timeStr);
			agv.setLastState(agv.getState());
			agvlog.info(sb.toString());
		}

		mainAction.main.agvMap.put(agv.getId(), agv);
	}

	/**
	 * 调度AGV，让其进入充电站或有序通过交管区
	 * 
	 * @param agvId
	 */
	public void dispatchAgv(int agvId, Double pointLon, Double pointLat) {
		Agv agv = mainAction.main.agvMap.get(agvId);

		List<ControlArea> controlAreaList = getControlAreaByCoordinate(pointLon, pointLat);
		/**
		 * 把不相关的交管区释放掉
		 */
		releaseControlArea(agv, pointLon, pointLat);
		/**
		 * 进入交管区
		 */
		if (controlAreaList.size() > 0) {
			logger.info("进入交管区");
			intoControlArea(controlAreaList, agv);
		}
	}

	/**
	 * 释放AGV占用的所有交管区
	 * 
	 * @param agv
	 */
	public void clearControlArea(Agv agv) {
		int agvId = agv.getId();
		// 当前座标没有在任何交管区里的时候，将当前AGV所占用的交管区释放掉
		for (Map.Entry<Integer, ControlArea> m : mainAction.main.controlAreaMap.entrySet()) {
			ControlArea ca = m.getValue();
			List<ControlRunAgv> newList = new ArrayList<ControlRunAgv>();
			if (ca.getRunAgvList().size() > 0) {
				for (ControlRunAgv caRunAgv : ca.getRunAgvList()) {
					if (caRunAgv.getAgvId() != agvId) {
						newList.add(caRunAgv);
					}
				}
				ca.setRunAgvList(newList);
			}

//			Boolean updateFlag = false;
			if (ca.getRunAgvList().size() == 0) {
				ca.setRunAgvId(0);
				if (ca.getFlag() == CaFlag.OFF.getCode()) {
					ca.setFlag(CaFlag.ON.getCode());
					logger.info("没在任何交管区里面,释放所占用的交管区");
				}
//				updateFlag = true;
				// 启动等待AGV
				boolean isClearCa = false;
				List<TrafficWait> newWaitAgvList = new ArrayList<TrafficWait>();
				for (TrafficWait tw : mainAction.main.waitAgvList) {
					if (tw.getCaId() == ca.getId()) {
						// 启动AGV
						int startOrStop = 2;// 启动
						byte[] data = CommandUtil.startOrStop(tw.getAgvId(), startOrStop);
						String note = tw.getAgvId() + "号AGV启动";
						mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());
						// 封闭交管区
						ca.setRunAgvId(tw.getAgvId());
						ca.setFlag(CaFlag.OFF.getCode());
						isClearCa = true;
						for (TrafficWait wa : mainAction.main.waitAgvList) {
							if (wa.getAgvId() != tw.getAgvId()) {
								newWaitAgvList.add(wa);
							}
						}
						break;
					}
				}
				if (isClearCa) {
					mainAction.main.waitAgvList = newWaitAgvList;
				}
				mainAction.main.controlAreaMap.put(ca.getId(), ca);
			}
			mainAction.main.controlAreaMap.put(ca.getId(), ca);
//			if(updateFlag){
//				String outTime = DateUtil.getTimeDate(new Date());
//				mainAction.main.updateCaLog(ca.getId(), agvId, outTime);
//			}
		}
	}

	/**
	 * 行驶进入交管区
	 * 
	 * @param controlArea
	 * @param agv
	 */
	private void intoControlArea(List<ControlArea> controlAreaList, Agv agv) {
		int agvId = agv.getId();
		/**
		 * 遍历交管区列表，判断是否需要停车等待
		 */
		boolean stopFlag = false;// 不用停车
		StringBuffer caIds = new StringBuffer();
		int mainCaId = 0;
		for (ControlArea controlArea : controlAreaList) {
			if (controlArea.getFlag() == CaFlag.OFF.getCode() && controlArea.getRunAgvList().size() > 0) {
				for (ControlRunAgv caRunAgv : controlArea.getRunAgvList()) {
					Agv runAgv = mainAction.main.agvMap.get(caRunAgv.getAgvId());
					if (runAgv.getLineLockGroup() == 0 && caRunAgv.getAgvId() != agvId) {
						stopFlag = true;
						break;
					} else {
						if (agv.getLineLockGroup() != runAgv.getLineLockGroup()) {
							stopFlag = true;
							break;
						}
					}
				}
				// 如果当前列表里有正在行驶的车辆，则false
				for (ControlRunAgv caRunAgv : controlArea.getRunAgvList()) {
					if (caRunAgv.getAgvId() == agvId) {
						stopFlag = false;
					}
				}
			}
			caIds.append(controlArea.getId() + ",");
			mainCaId = controlArea.getId();
		}
		/**
		 * 如果交管区是不可通行状态或交管区行驶AgvId不等于当前车辆则等待 如果交管区必须充电才可能进入，而当前AGV没有充电，也让AGV停止
		 */
		int as = AgvState.XS.getCode();

		if (stopFlag) {
			int startOrStop = 1;// 暂停
			byte[] data = CommandUtil.startOrStop(agvId, startOrStop);
			// 向车发送暂停等待指令
			String note = agvId + "号AGV暂停";
			mainAction.main.sendDataToAgv(data, note, AgvState.JG.getCode());
			// 保存等待的车号
			List<TrafficWait> waitAgvList = mainAction.main.waitAgvList;
			boolean isAdd = true;
			String[] controlAreaIds = caIds.toString().split(",");
			if (waitAgvList.size() > 0) {
				for (TrafficWait wa : waitAgvList) {
					if (wa.getAgvId() == agvId) {
						isAdd = false;
						wa.setControlAreaIds(controlAreaIds);
						wa.setCaId(mainCaId);
					}
				}
			}
			if (isAdd) {
				TrafficWait tw = new TrafficWait();
				tw.setControlAreaIds(controlAreaIds);
				tw.setAgvId(agvId);
				tw.setCaId(mainCaId);
				startOrStop = 2;// 启动
				byte[] restartData = CommandUtil.startOrStop(agvId, startOrStop);
				tw.setRestartData(restartData);// 启动指令
				tw.setdStr(HexUtil.byte2HexStr(restartData));
				waitAgvList.add(tw);
			}
			as = AgvState.JG.getCode();// 交管等待
		} else {
			for (ControlArea controlArea : controlAreaList) {
				if (controlArea.getFlag() == CaFlag.ON.getCode()) {
					controlArea.setFlag(CaFlag.OFF.getCode());
					logger.info("封闭交管区：" + controlArea.getName());
					// 插入一条进入交管区记录
					logger.info("进入交管区：" + controlArea.getName());
				}
				List<ControlRunAgv> runAgvList = controlArea.getRunAgvList();
				boolean addFlag = true;
				for (ControlRunAgv caRun : runAgvList) {
					if (caRun.getAgvId() == agvId) {
						addFlag = false;
					}
				}
				if (addFlag) {
					runAgvList.add(new ControlRunAgv(agvId, controlArea.getId(), agv.getLineLockGroup()));
					controlArea.setRunAgvList(runAgvList);
				}
				controlArea.setRunAgvId(controlArea.getRunAgvList().get(0).getAgvId());
				mainAction.main.controlAreaMap.put(controlArea.getId(), controlArea);
			}
		}
		if (as == AgvState.JG.getCode()) {// 交管等待
			agv.setCtrlState(as);
		}
		mainAction.main.agvMap.put(agv.getId(), agv);
	}

	/**
	 * 根据AGV的当前座标检查是否有交管区需要释放
	 * 
	 * @param agv
	 * @param pointLon
	 * @param pointLat
	 */
	private void releaseControlArea(Agv agv, double pointLon, double pointLat) {
		List<ControlArea> controlAreaList = getControlAreaByCoordinate(pointLon, pointLat);
		// 当前座标没有在任何交管区里的时候，将当前AGV所占用的交管区释放掉
		int agvId = agv.getId();
		for (Map.Entry<Integer, ControlArea> m : mainAction.main.controlAreaMap.entrySet()) {
			ControlArea ca = m.getValue();
			List<ControlRunAgv> newList = new ArrayList<ControlRunAgv>();
			boolean isClear = true;
			if (controlAreaList.size() > 0) {
				for (ControlArea c : controlAreaList) {
					if (ca.getId() == c.getId()) {
						isClear = false;
						break;
					}
				}
			}
			if (isClear && ca.getRunAgvList().size() > 0) {
				for (ControlRunAgv caRunAgv : ca.getRunAgvList()) {
					if (caRunAgv.getAgvId() != agvId) {
						newList.add(caRunAgv);
					}
				}
				ca.setRunAgvList(newList);
			}
			if (newList.size() == 0 && isClear) {
				if (ca.getFlag() == CaFlag.OFF.getCode()) {
					ca.setFlag(CaFlag.ON.getCode());
					logger.info("没在任何交管区里面,释放所占用的交管区");
				}
				// 启动等待AGV
				boolean isClearCa = false;
				List<TrafficWait> newWaitAgvList = new ArrayList<TrafficWait>();
				for (TrafficWait tw : mainAction.main.waitAgvList) {
					if (tw.getCaId() == ca.getId()) {
						// 启动AGV
						int startOrStop = 2;// 启动
						byte[] data = CommandUtil.startOrStop(tw.getAgvId(), startOrStop);
						String note = tw.getAgvId() + "号AGV启动";
						mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());
						// 封闭交管区
						Agv twAgv = mainAction.main.agvMap.get(tw.getAgvId());
						List<ControlRunAgv> nList = ca.getRunAgvList();
						nList.add(new ControlRunAgv(tw.getAgvId(), ca.getId(), twAgv.getLineLockGroup()));
						ca.setRunAgvList(nList);
						ca.setRunAgvId(tw.getAgvId());
						ca.setFlag(CaFlag.OFF.getCode());
						isClearCa = true;
						for (TrafficWait wa : mainAction.main.waitAgvList) {
							if (wa.getAgvId() != tw.getAgvId()) {
								newWaitAgvList.add(wa);
							}
						}
						break;
					}
				}
				if (isClearCa) {
					mainAction.main.waitAgvList = newWaitAgvList;
				}
				mainAction.main.controlAreaMap.put(ca.getId(), ca);
			}
			mainAction.main.controlAreaMap.put(ca.getId(), ca);
		}
	}

	public void releaseControlArea(int caId) {
		ControlArea ca = mainAction.main.controlAreaMap.get(caId);
		if (ca == null) {
			logger.info("释放交管时没有获取到对接的交管区！！！！");
		} else {
//			ca.setRunAgvId(0);
			ca.setRunAgvList(new ArrayList<ControlRunAgv>());
			ca.setFlag(CaFlag.ON.getCode());
			// 启动等待AGV
			boolean isClearCa = false;
			List<TrafficWait> newWaitAgvList = new ArrayList<TrafficWait>();
			List<TrafficWait> waList = mainAction.main.waitAgvList;
			mainAction.trafficWaitSort(waList);// 对等待AGV列表按照与基点的距离升序排序
			for (TrafficWait tw : waList) {
				if (tw.getCaId() == ca.getId()) {
					// 启动AGV
					int startOrStop = 2;// 启动
					byte[] data = CommandUtil.startOrStop(tw.getAgvId(), startOrStop);
					String note = tw.getAgvId() + "号AGV启动";
					mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());
					// 封闭交管区
					Agv twAgv = mainAction.main.agvMap.get(tw.getAgvId());
					List<ControlRunAgv> nList = ca.getRunAgvList();
					nList.add(new ControlRunAgv(tw.getAgvId(), ca.getId(), twAgv.getLineLockGroup()));
					ca.setRunAgvList(nList);
					ca.setRunAgvId(ca.getRunAgvList().get(0).getAgvId());
					ca.setFlag(CaFlag.OFF.getCode());
					isClearCa = true;
					for (TrafficWait wa : mainAction.main.waitAgvList) {
						if (wa.getAgvId() != tw.getAgvId()) {
							newWaitAgvList.add(wa);
						}
					}
					break;
				}
			}
			if (isClearCa) {
				mainAction.main.waitAgvList = newWaitAgvList;
			}
			mainAction.main.controlAreaMap.put(ca.getId(), ca);
		}
	}

	/**
	 * 根据座标获取所有相关的交管区
	 * 
	 * @param pointLon
	 * @param pointLat
	 * @return
	 */
	private List<ControlArea> getControlAreaByCoordinate(double pointLon, double pointLat) {
		Point2D.Double point = new Point2D.Double(pointLon, pointLat);
		List<ControlArea> controlAreaList = new ArrayList<ControlArea>();
		Map<Integer, ControlArea> controlAreaMap = mainAction.main.controlAreaMap;
		for (Map.Entry<Integer, ControlArea> m : controlAreaMap.entrySet()) {
			ControlArea ca = m.getValue();
			if (ca.getShape() != null) {
				if (ca.getShape().contains(point)) {
					controlAreaList.add(ca);
				}
			}
		}
		return controlAreaList;
	}

	private List<FreeArea> getFreeAreaByCoordinate(double pointLon, double pointLat) {
		Point2D.Double point = new Point2D.Double(pointLon, pointLat);
		List<FreeArea> freeAreaList = new ArrayList<FreeArea>();
		Map<Integer, FreeArea> freeAreaMap = mainAction.main.freeAreaMap;
		for (Map.Entry<Integer, FreeArea> m : freeAreaMap.entrySet()) {
			FreeArea fa = m.getValue();
			if (fa.getShape() != null) {
				if (fa.getShape().contains(point)) {
					freeAreaList.add(fa);
				}
			}
		}
		return freeAreaList;
	}

	private LimitArea getLimitAreaByCoordinate(double pointLon, double pointLat) {
		Point2D.Double point = new Point2D.Double(pointLon, pointLat);
		LimitArea limitArea = null;
		Map<Integer, LimitArea> limitAreaMap = mainAction.main.limitAreaMap;
		for (Map.Entry<Integer, LimitArea> m : limitAreaMap.entrySet()) {
			LimitArea la = m.getValue();
			if (la.getShape() != null) {
				if (la.getShape().contains(point)) {
					limitArea = la;
				}
			}
		}
		return limitArea;
	}

	/**
	 * 向Agv重发指令
	 * 
	 * @param agvId
	 * @param data
	 */
	public void repeatData(int agvId, byte[] data, int ctrlState) {
		Agv agv = mainAction.main.agvMap.get(agvId);
		Date lastSendTime = agv.getLastSendTime();
		String note = "向" + agvId + "号AGV重发指令";
		if (lastSendTime != null) {
			Date currentDate = new Date();
			long t1 = lastSendTime.getTime();
			long t2 = currentDate.getTime();
			long t3 = (t2 - t1) / 1000;
			logger.info("Agv" + agv.getId() + "距离上次发送时间：" + t3 + "秒");
			if (t3 > 10) {
				mainAction.main.sendDataToAgv(data, note, ctrlState);
				agv.setLastSendTime(new Date());
				mainAction.main.agvMap.put(agv.getId(), agv);
			}
		}
	}

	/**
	 * 解释指令数据的意思
	 * 
	 * @return
	 */
	private String convertData(byte[] data) {
		// AGV车号
		int agvId = data[NO_BIT];
		// agv状态
		int state = data[STATE_BIT];
		String stateStr = AgvState.getValueByCode(state);
		return "AGV:" + agvId + ",状态：" + stateStr;
	}

	public Map<String, Object> analyseData(byte[] data) {
		Map<String, Object> map = new HashMap<String, Object>();
		// AGV车号
		map.put("agvId", data[NO_BIT]);
		// agv状态
		map.put("state", data[STATE_BIT]);
		// 获取地标
		map.put("site", CommandUtil.getGuidepost4Data(data));
		map.put("currentX", CommandUtil.getMapX4Data(data));
		map.put("currentY", CommandUtil.getMapY4Data(data));
		return map;
	}

	/**
	 * AGV到达地标
	 * 
	 * @param agvId
	 * @param state
	 * @param gpId
	 */
	public void agvParking(Agv agv, Guidepost gp) {

		// 充电点判断
		if (gp.getType() == GpType.CD.getCode()) {
			if (agv.getBattery() < 60) {
				agv.setLowCharger(true);
			} else {
				agv.setLowCharger(false);
			}
			agv.setChargerTimes(new Date());
			agv.setIsMultiPath(0);
			agv.setStartPoint(0);
			agv.setEndPoint(0);
		}

		// 临时泊位、对接工位
		if (gp.getType() == GpType.LS.getCode() || gp.getType() == GpType.GW.getCode()) {
			agv.setIsMultiPath(0);
			agv.setStartPoint(0);
			agv.setEndPoint(0);
		}

		// IGV到达选择点
		if (gp.getType() == GpType.XZD.getCode()) {
			xzdCharger(agv, gp);
		}
		// 对接工位退出点
		if (gp.getType() == GpType.LK.getCode()) {
			lkCharger(agv, gp);
		}
		// 如果是重定位点的话，找寻位于重定位点工序的机台
		if (gp.getType() == GpType.CDW.getCode()) {
			if (gp.getStep() == Step.JPX.getCode()) {
				Station nextStation = getFreeStationByStep2(Step.JPX.getCode(), agv);
				if (nextStation != null) {
					Park nextPark = mainAction.getParkByStationName(nextStation.getName());
					if (checkAgvGoal2(nextPark, agv)) {
						mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
					}
				}
			} else if (gp.getStep() == Step.KSS.getCode()) {
				Guidepost xzdNum = this.mainAction.getGuidepostByStep4Station(gp.getStep(), gp.getNextStep(), agv);
				if (xzdNum == null) {
					String msg = "该工序选择点已被占用，在重定位点等待";
					this.mainAction.main.sendMsgByWs(agv.getId() + "", msg);
				} else if (checkAgvGoal2(xzdNum.getNum(), agv)) {
					agv.setIsStep(gp.getNextStep());
					this.mainAction.taskAction.multiPath4z(agv, gp.getNum(), xzdNum.getNum());
				}
			} else {
				Guidepost xzdNum = mainAction.getGuidepostByStep4Station(gp.getStep(), 0, agv);
				if (xzdNum == null) {
					String msg = "该工序选择点已被占用，在重定位点等待";
					mainAction.main.sendMsgByWs(agv.getId() + "", msg);
				} else {
					if (checkAgvGoal2(xzdNum.getNum(), agv)) {
						agv.setIsStep(gp.getNextStep());
						mainAction.taskAction.multiPath4z(agv, gp.getNum(), xzdNum.getNum());
					}
				}
			}
		}
		// 充电桩退出点
		if (gp.getType() == GpType.CDLK.getCode()) {
			mainAction.taskAction.multiPath4z(agv, gp.getNum(), agv.getGoal());
		}
	}

	/**
	 * 机台退出点逻辑判断
	 * 
	 * @param agv
	 * @param gp
	 */
	public void lkCharger(Agv agv, Guidepost gp) {
		Park park = mainAction.getParkByOutNum(gp.getNum());
		if (park == null) {
			logger.info("获不到对接的泊位！错误地标号：[" + gp.getNum() + "]");
		} else {
			agv.setIsStep(gp.getNextStep());
			agv.setNextStep(park.getNextStep());
			Step step = Step.getStepByCode(park.getStep());
			for (Map.Entry<String, Station> sm : mainAction.main.stationMap.entrySet()) {
				Station ss = sm.getValue();
				if (ss.getJoinAgvId() == agv.getId()) {
					ss.setJoinAgvId(0);
					mainAction.main.stationMap.put(ss.getName(), ss);
				}
			}
			Station station = mainAction.getStationByName(park.getStationName());
			if (station.getType() == 1) {
				agv.setpGroup(station.getPGroup());
				agv.setpType(station.getPType());
				station.setLastJoinTime(new Date());
			}
			agv.setLastJoinStationId(station.getId());
			agv.setLastJoinStationName(station.getName());
			agv.setParkId(0);
			logger.info("退出点：" + park.getName() + ",工序：" + step.getCode() + "[" + step.getName() + "]");
			switch (step) {
			case ZRS:
				// 离开制绒上料
				toNextPark4zrs(agv, park);
				break;
			case ZRX:
				// 离开制绒下料
				// 低电量去往该工序的充电点进行充电
				if (agv.getBattery() < 60) {// 如果电池余量少于60
					List<Park> parks = mainAction.taskAction.getTempChargerPark(Step.KSS.getCode(), park);// 获取当前工序公用的充电桩
					if (parks.size() > 0) {// 如果当前工序共用的充电桩数量大于0
						for (Park chPark : parks) {
							if (checkAgvGoal2(chPark, agv)) {
								mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), chPark.getOutNum());
								return;
							}
						}
					}
				}
				if (agv.getLoadState() == LoadState.KM.getCode()) {// 如果负载状态等于上空下满
					Guidepost xzNum = mainAction.getGuidepostByStep2(Step.KSS.getCode(), 0);// 根据Step获取地标type为选择点的列表，分区域式选择点
					if (xzNum != null) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
					}
				}
//				toNextPark4zrx(agv, park);
				break;
			case KSS:
				// 离开扩散上料
				toNextPark4kss(agv, park);
				break;
			case KSX:
				// 离开扩散下料
				if (agv.getLoadState() == LoadState.MK.getCode()) {
					Guidepost xzNum = mainAction.getGuidepostByStep2(Step.SE.getCode(), park.getXzdNumItem());
					if (xzNum != null) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
					}
				}
				break;
			case SE:
				// 离开激光
				if (agv.getLoadState() == LoadState.KM.getCode()) {
					Guidepost xzNum = mainAction.getGuidepostByStep2(Step.QY.getCode(), park.getXzdNumItem());
					if (xzNum != null) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
					}
				}
				break;
			case QY:
				// 离开前氧
				// 如果电量低于60，则强制去充电桩充电
				if (agv.getBattery() < 60) {
					List<Park> parks = mainAction.taskAction.getTempChargerPark4Priority(Step.QY.getCode(), park);
					if (parks.size() > 0) {
						for (Park chPark : parks) {
							if (checkAgvGoal2(chPark, agv)) {
								mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), chPark.getOutNum());
								return;
							}
						}
					}
				}
				if (agv.getLoadState() == LoadState.MK.getCode()) {
					Guidepost xzNum = mainAction.getGuidepostByStep2(Step.JPS.getCode(), park.getXzdNumItem());
					if (xzNum != null) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
					}
				}
				break;
			case JPS:
				// 电量低于60就去该工序充电桩充电
				if (agv.getBattery() < 60) {
					List<Park> parks = mainAction.taskAction.getTempChargerPark(Step.JPS.getCode(), park);
					if (parks.size() > 0) {
						for (Park chaPark : parks) {
							if (checkAgvGoal2(park, agv)) {
								mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), chaPark.getOutNum());
								return;
							}
						}
					}
				}
				// 离开碱抛上料
				if (agv.getLoadState() == LoadState.KM.getCode()) {
					Guidepost xzNum = mainAction.getGuidepostByStep2(Step.KSX.getCode(), 0);
					if (xzNum != null) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
					}
				}

				break;
			case JPX:
				// 离开碱抛下料
				if (agv.getBattery() < 60) {
					List<Park> parks = mainAction.taskAction.getTempPublicChargerParkToStep(Step.HYS.getCode(), park);
					if (parks.size() > 0) {
						for (Park chPark : parks) {
							if (checkAgvGoal2(chPark, agv)) {
								mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), chPark.getOutNum());
								return;
							}
						}
					}
				}

				Station nextStation = getFreeStationByPGroup(Step.HYS.getCode(), agv);
				if (agv.getLoadState() == LoadState.MK.getCode() && nextStation != null) {
					Guidepost xzNum = mainAction.getGuidepostByStep2(Step.HYS.getCode(), nextStation.getLimit());
					if (xzNum != null) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
					}
				} else {
					List<Park> tempPark = mainAction.taskAction.getTempPark(Step.HYS.getCode(), agv.getpGroup());
					if (tempPark.size() > 0) {
						for (Park park2 : tempPark) {
							if (checkAgvGoal2(park2, agv)) {
								if (park2.getType() == 2) {
									mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getOutNum());
								} else {
									mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getDot());
								}
							}
						}
					}
				}
				break;
			case HYS:
				// 离开后氧上料
				if (agv.getLoadState() == LoadState.KM.getCode()) {
					Guidepost xzNum = mainAction.getGuidepostByStep2(Step.JPFK.getCode(), park.getXzdNumItem());
					if (xzNum != null) {
						if (checkAgvGoal2(park, agv))
							mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzNum.getNum());
					}
				}
				break;
			case JPFK:
				// 离开碱抛返空
				clearControlArea(agv);
				nextStation = getFreeStationByStepOrOutintitry(Step.JPX.getCode(), agv);
				if (nextStation != null) {
					Park nextPark = mainAction.getParkByStationName(nextStation.getName());
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
				}
				break;
			case HYX:
				// 离开后氧下料
				Guidepost xzNum = mainAction.getGuidepostByStep(Step.ALD.getCode());
				if (xzNum != null) {
//						if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), xzNum.getNum());
//						}
				}
				break;
			case ALD:
				// 离开ALD
				// 如果装满料了直接去往PE背膜
//					if(agv.getLoadState() == LoadState.KK.getCode()) {
				Park trunPark = mainAction.getParkByOutNum(park.getTrunNum());
				if (checkAgvGoal2(trunPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), park.getTrunNum());
				}
//					}
				break;
			case ALDX:

				xzNum = mainAction.getGuidepostByStep2(Step.PEB.getCode(), park.getXzdNumItem());
				if (xzNum != null) {
					if (checkAgvGoal2(xzNum.getNum(), agv)) {
						mainAction.taskAction.multiPath4z(agv, gp.getNum(), xzNum.getNum());
					}
				}

				break;
			case PEB:
				// 离开PE背膜
//					 if(agv.getLoadState() == LoadState.KK.getCode()) {
				trunPark = mainAction.getParkByOutNum(park.getTrunNum());
				if (checkAgvGoal2(trunPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), park.getTrunNum());
				}
//					}
				break;
			case PEBX:
//					if(agv.getLoadState() == LoadState.MK.getCode()) {
//					nextStation = getFreeStationByPGroup(Step.PEZ.getCode(), agv);
//					if (nextStation != null) {
//						Park nextPark = mainAction.getParkByStationName(nextStation.getName());
//						if (checkAgvGoal2(nextPark, agv)) {
//							mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
//						}
//					}
				xzNum = mainAction.getGuidepostByStep2(Step.PEZ.getCode(), park.getXzdNumItem());
				if (xzNum != null) {
					if (checkAgvGoal2(xzNum.getNum(), agv)) {
						mainAction.taskAction.multiPath4z(agv, gp.getNum(), xzNum.getNum());
					}
				}
//					}
				break;
			case PEZ:
				// 离开PE正膜
				if (agv.getLoadState() == LoadState.KK.getCode()) {
//						if(checkAgvGoal2(park, agv)) {
//							mainAction.taskAction.multiPath4z(agv, gp.getNum(),park.getTrunNum());
//						}
					/**
					 * 测试代码
					 */
					xzNum = mainAction.getGuidepostByStep2(Step.SW.getCode(), park.getXzdNumItem());
					if (xzNum != null) {
//								if (checkAgvGoal2(nextPark, agv)) {
						mainAction.taskAction.multiPath4z(agv, gp.getNum(), xzNum.getNum());
//								}
					}
				}

				break;
			case PEZX:
//					if(agv.getLoadState() == LoadState.MK.getCode()) {
				nextStation = getFreeStationByPGroup4OutTinity(Step.SW.getCode(), agv);
				if (nextStation != null) {
					Park nextPark = mainAction.getParkByStationName(nextStation.getName());
					if (checkAgvGoal2(nextPark, agv)) {
						mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
					}
				}
//					}
				break;
			case SW:
				// 离开丝网
//					if(agv.getLoadState() == LoadState.KM.getCode()) {
				xzNum = mainAction.getGuidepostByStep(Step.HYX.getCode());
				if (xzNum != null) {
//						if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), xzNum.getNum());
//						}
				}
//					}
				break;
			}
		}
		if (park.getAgvId() == agv.getId()) {
			park.setAgvId(0);
			mainAction.main.parkMap.put(park.getId(), park);
		}
	}

	/**
	 * 机台询问点逻辑判断
	 * 
	 * @param agv
	 * @param gp
	 */
	public void xzdCharger(Agv agv, Guidepost gp) {
		if (!ControlAreaFlag(agv))
			return;
		// 碱抛下料/后氧湿花篮
		if (gp.getStep() == Step.HYS.getCode()) {
			Station station = getFreeStationByOutintitry4SwitchNum(gp.getStep(), agv, gp.getXzdNumItem());
			if (station != null) {// 如果有获取到机台，直接让小车去机台
				Park staPark = mainAction.getParkByStationName(station.getName());
				mainAction.taskAction.multiPath4z(agv, gp.getNum(), staPark.getOutNum());
			} else {
				List<Park> tempPark = mainAction.taskAction.getTempPark(gp.getStep(), agv.getpGroup(),
						gp.getXzdNumItem());
				if (tempPark.size() > 0) {
					for (Park p : tempPark) {
						if (checkAgvGoal2(p, agv)) {
							if (p.getType() == 2) {
								mainAction.taskAction.multiPath4z(agv, gp.getNum(), p.getOutNum());
							} else {
								mainAction.taskAction.multiPath4z(agv, gp.getNum(), p.getDot());
							}
						}
					}
				}
			}
		} else if (gp.getStep() == Step.JPFK.getCode()) {
			Station station = getFreeStationByStep4Intinity(gp.getStep(), agv);
			if (station != null) {// 如果有获取到机台，直接让小车去机台
				Park staPark = mainAction.getParkByStationName(station.getName());
				mainAction.taskAction.multiPath4z(agv, gp.getNum(), staPark.getOutNum());
			} else {
				List<Park> tempPark = mainAction.taskAction.getTempPark(gp.getStep(), agv.getpGroup(),
						gp.getXzdNumItem());
				if (tempPark.size() > 0) {
					for (Park park2 : tempPark) {
						if (checkAgvGoal2(park2, agv)) {
							if (park2.getType() == 2) {
								mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getOutNum());
							} else {
								mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getDot());
							}
						}
					}
				}
			}
		} else if (gp.getStep() == Step.ZRS.getCode()) {// 制绒空花篮或者制绒下料，不区分物料状态
//			Station nextStation = getFreeStationByStep2(gp.getStep(), agv);
			Station nextStation = getFreeStationByStep4Intinity(Step.ZRS.getCode(),agv);
			// 是否去等待泊位状态字段
			boolean waitFlag = true;
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
					waitFlag = false;
				}
			}
			// 无空闲工位可前往，将去往该工序等待泊位
			if (waitFlag) {
				// 获取该工序的泊位列表
				List<Park> nextPark = mainAction.taskAction.getTempPark(gp.getStep());
				for (Park park2 : nextPark) {
					if (checkAgvGoal2(park2, agv)) {
						// 等待泊位时特殊泊位点(带充电桩功能)
						if (park2.getType() == 2) {
							mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getOutNum());
						} else {
							mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getDot());
						}
					}
				}
			}
		} else if (gp.getStep() == Step.ZRX.getCode() && agv.getLoadState() == LoadState.KK.getCode()) {
			Station nextStation = getFreeStationByStep4SwitchNum(gp.getStep(), agv, gp.getXzdNumItem());
			// 是否去等待泊位状态字段
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
				}
			}
		} else if (gp.getStep() == Step.KSX.getCode()) {
			Station nextStation = getFreeStationByStep2(Step.KSX.getCode(), agv);
			boolean waitFlag = true;
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
					waitFlag = false;
				}
			}

			if (waitFlag) {
				// 获取该工序的泊位列表
				List<Park> nextPark = mainAction.taskAction.getTempPark(gp.getStep());
				if (nextPark.size() > 0) {
					for (Park park2 : nextPark) {
						if (checkAgvGoal2(park2, agv)) {
							// 等待泊位时特殊泊位点(带充电桩功能)
							if (park2.getType() == 2) {
								mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getOutNum());
							} else {
								mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getDot());
							}
						}
					}
				}
			}
		} else if (gp.getStep() == Step.SE.getCode()) {
			Station nextStation = getFreeStationByStep4SwitchNumOrGrounp(gp.getStep(), agv, gp.getXzdNumItem());
			// 是否去等待泊位状态字段
//				boolean waitFlag = true;
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
//						waitFlag = false;
				}
			}
		} else if (gp.getStep() == Step.QY.getCode()) {
//				Station nextStation = getFreeStationByStep4SwitchNumOrGrounp(gp.getStep(), agv, gp.getXzdNumItem());
			Station nextStation = getFreeStationByOutintitry(gp.getStep(), agv);
			// 是否去等待泊位状态字段
//				boolean waitFlag = true;
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
//						waitFlag = false;
				}
			}
		} else if (gp.getStep() == Step.PEZ.getCode()) {
			Station nextStation = getFreeStationByPGroup4(gp.getStep(), agv);
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
				}
			}

		} else if (gp.getStep() == Step.SW.getCode()) {
			Station nextStation = getFreeStationByPGroup4OutTinityToPark(gp.getStep(), agv);
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
				}
			}
		} else if (gp.getStep() == Step.HYX.getCode()) {
			Station nextStation = getFreeStationByStep2(gp.getStep(), agv);
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
				}
			}
		} else if (gp.getStep() == Step.KSS.getCode()) {// 扩散工序选择点
			Station nextStation = null;
			nextStation = getFreeStationByPGroup4OutTinity(gp.getStep(), agv);
			// 放行标志
			if (nextStation != null) {
				Park staPark = mainAction.getParkByStationName(nextStation.getName());
				mainAction.taskAction.multiPath4z(agv, gp.getNum(), staPark.getOutNum());
			} else {
//				List<Park> nextPark = mainAction.taskAction.getTempPark(998);
//				for (Park park2 : nextPark) {
//					if (checkAgvGoal2(park2, agv)) {
//						agv.setNextStep(Step.KSS.getCode());
//						if (park2.getType() == 2) {
//							mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getOutNum());
//						} else {
//							mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getDot());
//						}
//					}
//				}
			}
		} else {
			Station nextStation = null;
			nextStation = getFreeStationByPGroup4OutTinity(gp.getStep(), agv);
			if (nextStation != null) {
				Park nextPark = mainAction.getParkByStationName(nextStation.getName());
				if (checkAgvGoal2(nextPark, agv)) {
					mainAction.taskAction.multiPath4z(agv, gp.getNum(), nextPark.getOutNum());
				} else if (gp.getStep() != Step.ZRX.getCode() && gp.getStep() != Step.KSS.getCode()) {
					List<Park> nextParks = mainAction.taskAction.getTempPark(gp.getStep());
					for (Park park2 : nextParks) {
						if (checkAgvGoal2(park2, agv)) {
							if (park2.getType() == 2) {
								mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getOutNum());
							} else {
								mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getDot());
							}
						}
					}
				}
			} else if (gp.getStep() != Step.ZRX.getCode() && gp.getStep() != Step.KSS.getCode()) {
				List<Park> nextPark = mainAction.taskAction.getTempPark(gp.getStep());
				for (Park park2 : nextPark) {
					if (checkAgvGoal2(park2, agv)) {
						if (park2.getType() == 2) {
							mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getOutNum());
						} else {
							mainAction.taskAction.multiPath4z(agv, gp.getNum(), park2.getDot());
						}
					}
				}
			}
		}
	}

	/**
	 * 是否可以退出后氧上料机台:根据对应工序、线别
	 * 
	 * @param agv
	 * @param gp
	 * @return true：可退出 false：不可退出
	 */
	public boolean isReturnStation(Agv agv, int step) {
		// 机台是否放行状态
		boolean returnStationFlag = false;
		Station nextStation = getFreeStationByPGroup(step, agv);
		boolean isGO = true;// 机台放行标志位
		if (nextStation != null) {
			Park nextPark = mainAction.getParkByStationName(nextStation.getName());
			if (checkAgvGoal2(nextPark, agv)) {
				returnStationFlag = true;
			} else {
				isGO = false;
			}
		} else {
			isGO = false;
		}
		// 当获取不到相关的机台时，去往待区
		if (!isGO) {
			List<Park> dmParkList = mainAction.taskAction.getTempPark(step, agv.getpGroup());
			if (dmParkList.size() > 0) {
				for (Park park2 : dmParkList) {
					if (checkAgvGoal2(park2, agv)) {
						returnStationFlag = true;
					}
				}
			}
		}

		return returnStationFlag;
	}

	/**
	 * 是否可以退出后氧上料机台:根据对应工序
	 * 
	 * @param agv
	 * @param gp
	 * @return true：可退出 false：不可退出
	 */
	public boolean isReturnStation4Step(Agv agv, int step) {
		// 机台是否放行状态
		boolean returnStationFlag = false;
		Station nextStation = getFreeStationByStepOrOutintitry(Step.JPX.getCode(), agv);
		boolean isGO = true;// 机台放行标志位
		if (nextStation != null) {
			Park nextPark = mainAction.getParkByStationName(nextStation.getName());
			if (checkAgvGoal2(nextPark, agv)) {
				returnStationFlag = true;
			} else {
				isGO = false;
			}
		} else {
			isGO = false;
		}
		// 当获取不到相关的机台时，去往待区
		if (!isGO) {
			List<Park> dmParkList = mainAction.taskAction.getTempPark(step, agv.getpGroup());
			if (dmParkList.size() > 0) {
				for (Park park2 : dmParkList) {
					if (checkAgvGoal2(park2, agv)) {
						returnStationFlag = true;
					}
				}
			}
		}

		return returnStationFlag;
	}

	public void choosePark(int step, Agv agv) {
		Station qStation = getFreeStationByPGroup(step, agv);
		List<Park> tempParkList = mainAction.taskAction.getTempPark(step);
		ParkBean.ItemSort(tempParkList);
		if (qStation == null) {
			for (Park p : tempParkList) {
				boolean isGo = checkAgvGoal2(p, agv);
				if (isGo) {
					if (p.getType() == 2) {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), p.getOutNum());
					} else {
						mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), p.getDot());
					}
					break;
				}
			}
		} else {
			boolean cFlag = false;
			for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
				if (m.getValue().getGoal() == qStation.getInNum() && agv.getId() != m.getValue().getId()) {
					logger.info("目的地已有车，不能前往！！！");
					cFlag = true;
					return;
				}
			}
			if (cFlag) {
				for (Park p : tempParkList) {
					boolean isGo = checkAgvGoal2(p, agv);
					if (isGo) {
						if (p.getType() == 2) {
							mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), p.getOutNum());
						} else {
							mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), p.getDot());
						}
						break;
					}
				}
			} else {
				qStation.setJoinAgvId(agv.getId());
				mainAction.main.stationMap.put(qStation.getName(), qStation);
				agv.setGoal(qStation.getInNum());
				mainAction.main.agvMap.put(agv.getId(), agv);
				mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), qStation.getInNum());
			}
		}
	}

	/**
	 * 通过遍历AGV列表检查是否有AGV停靠在泊位上
	 * 
	 * @param park
	 * @return
	 */
	public boolean checkAgvGoal(Park park) {
		boolean flag = true;
		for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
			if (m.getValue().getGoal() == park.getDot() || m.getValue().getParkId() == park.getId()
					|| m.getValue().getLastPoint() == park.getDot() || m.getValue().getLastPoint() == park.getOutNum()
					|| m.getValue().getGoal() == park.getOutNum()) {
				flag = false;
			}
		}
		return flag;
	}

	/**
	 * 判断有车前往则不派车过去 true：可以派车 false：不可派车
	 * 
	 * @param park
	 * @param agv
	 * @return
	 */
	public boolean checkAgvGoal2(Park park, Agv agv) {
		boolean flag = true;
		for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
			if ((m.getValue().getGoal() == park.getOutNum() || m.getValue().getLastPoint() == park.getDot()
					|| m.getValue().getParkId() == park.getId() || m.getValue().getGoal() == park.getDot()
					|| m.getValue().getLastPoint() == park.getOutNum()) && m.getValue().getId() != agv.getId()) {
				flag = false;
				String msg = "目的地：" + park.getName() + "已有车辆前往，且无其他对应空位，等待！占用车辆：" + m.getValue().getId();
				mainAction.main.sendMsgByWs(agv.getId() + "", msg);
				break;
			}
		}
		return flag;
	}

	/**
	 * 判断是否已经有其他车辆前往该泊位，true为没有车前往、false为已经有车前往
	 * 
	 * @param gp
	 * @param agv
	 * @return
	 */
	public boolean checkAgvGoal2(int gp, Agv agv) {
		boolean flag = true;
		for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
			if ((m.getValue().getGoal() == gp || m.getValue().getLastPoint() == gp)
					&& m.getValue().getId() != agv.getId()) {
				flag = false;
				String msg = "目的地：" + gp + "已有车辆前往，且无其他对应空位，等待！占用车辆：" + m.getValue().getId();
				mainAction.main.sendMsgByWs(agv.getId() + "", msg);
			}
		}
		return flag;
	}

	/**
	 * 
	 * @param pGroup
	 * @param step
	 * @param agv
	 * @return
	 */
	public boolean checkParkByGroup(int pGroup, int step, Agv agv) {
		boolean flag = true;
		for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
			for (Map.Entry<Integer, Park> pm : mainAction.main.parkMap.entrySet()) {
				Park p = pm.getValue();
				if ((m.getValue().getGoal() == p.getOutNum() || m.getValue().getLastPoint() == p.getDot())
						&& m.getValue().getId() != agv.getId() && p.getpGroup() == pGroup && p.getStep() == step) {
					flag = false;
				}
			}
		}
		return flag;
	}

	/**
	 * 检查当前线别是否已经有车
	 * 
	 * @param station
	 * @param agv
	 * @return
	 */
	public boolean checkStation(Station station, Agv agv) {
		boolean flag = true;
		for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
			if ((m.getValue().getGoal() == station.getInNum() || m.getValue().getId() == station.getJoinAgvId())
					&& m.getValue().getId() != agv.getId()) {
				flag = false;
			}
		}
		return flag;
	}

	/**
	 * 移动制绒工序的待命AGV
	 */
//	public void shiftAgv4zrs() {
//		// 处理制绒上料前充电及等待点位上的车
//		List<Agv> cagvList = new ArrayList<Agv>();
//		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
//			if ((am.getValue().getLastPoint() == 100 || am.getValue().getLastPoint() == 102
//					|| am.getValue().getLastPoint() == 105 || am.getValue().getLastPoint() == 107)
//					&& (am.getValue().getState() == AgvState.DD.getCode()
//							|| am.getValue().getState() == AgvState.CD.getCode())) {
//				cagvList.add(am.getValue());
//			}
//		}
//		// 如果充电位有车则检查是否有机台要料
//		if (cagvList.size() > 0) {
//			for (Agv ca : cagvList) {
//				//Station qStation = getFreeStationByPType(Step.ZRS.getCode(), ca);
//				Station qStation = getFreeStationByPGroup(Step.ZRS.getCode(), ca);
//				if (qStation != null) {
//					boolean isRun = true;
//					for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
//						if (m.getValue().getGoal() == qStation.getInNum() && ca.getId() != m.getValue().getId()) {
//							logger.info("目的地已有车，不能前往！！！充电AGV：" + ca.getId() + ",工位AGV:" + m.getValue().getId());
//							isRun = false;
//						}
//					}
//					if (isRun) {
//						qStation.setJoinAgvId(ca.getId());
//						mainAction.main.stationMap.put(qStation.getName(), qStation);
//						ca.setGoal(qStation.getInNum());
//						mainAction.main.agvMap.put(ca.getId(), ca);
//						joinComplete(ca.getId());
//					}
//				} else {
//					logger.info("没有制绒上料机要料！！！！！！");
//				}
//			}
//		}
//	}

	public void shiftAgv4zrs() {
		List<Agv> cagvList = new ArrayList<Agv>();
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.ZRS.getCode());
		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
			Agv agv = am.getValue();
			for (Park park : tempPark) {
				if (agv.getLoadState() == LoadState.MK.getCode()
						&& (agv.getState() == AgvState.CD.getCode() || agv.getState() == AgvState.DD.getCode())
						&& agv.getLastPoint() == park.getDot()) {
					cagvList.add(agv);
				}
			}
		}
		if (cagvList.size() > 0) {
			for (Agv ca : cagvList) {
				long nowTimes = (new Date()).getTime();
				long cTimes = (nowTimes - (ca.getChargerTimes().getTime())) / 1000;
				if (cTimes > mainAction.main.chargeDuration) {
					Station station = getFreeStationByStep4Intinity(Step.ZRS.getCode(), ca);
					if (station != null) {
						Park staPark = mainAction.getParkByStationName(station.getName());
						Park aPark = mainAction.getParkByDot(ca.getLastPoint());
						if (checkAgvGoal2(staPark, ca) && station.getLimit() == aPark.getXzdNumItem()) {
							if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
								ca.setGoal(staPark.getOutNum());
								mainAction.main.agvMap.put(ca.getId(), ca);
								mainAction.agvAction.joinComplete(ca.getId());
							} else {
								mainAction.taskAction.multiPath4z(ca, aPark.getDot(), staPark.getDot());
							}
						}
						break;
					} else {
						String msg = "制绒上料机台无停靠点,等待！";
						mainAction.main.sendMsgByWs(ca.getId() + "", msg);
					}
				} else {
					long i = mainAction.main.chargeDuration - cTimes;
					String msg = "充电倒计时：" + i;
					mainAction.main.sendMsgByWs(ca.getId() + "", msg);
				}

			}
		}

		cagvList = new ArrayList<Agv>();
		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
			Agv agv = am.getValue();
			for (Park park : tempPark) {
				if (agv.getLoadState() == LoadState.MK.getCode()
						&& (agv.getState() == AgvState.CD.getCode() || agv.getState() == AgvState.DD.getCode())
						&& agv.getLastPoint() == park.getDot()) {
					cagvList.add(agv);
				}
			}
		}

		if (cagvList.size() > 0) {
			for (Agv ca : cagvList) {
				Guidepost xzdGp = mainAction.getGuidepostByStep2(Step.ZRS.getCode(), 1);
				Park aPark = mainAction.getParkByDot(ca.getLastPoint());
				long nowTimes = (new Date()).getTime();
				long cTimes = (nowTimes - (ca.getChargerTimes().getTime())) / 1000;
				if (cTimes > mainAction.main.chargeDuration) {
					// 0为制绒选择点之后的充电桩待命点，为机台响应而准备，非0为扩散充电待命点，如果制绒选择点没车，派车过去制绒选择点
					if (xzdGp != null && checkAgvGoal2(xzdGp.getNum(), ca) && aPark.getXzdNumItem() != 0) {
						if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
							ca.setGoal(xzdGp.getNum());
							mainAction.main.agvMap.put(ca.getId(), ca);
							mainAction.agvAction.joinComplete(ca.getId());
						} else {
							mainAction.taskAction.multiPath4z(ca, aPark.getDot(), xzdGp.getNum());
						}
					} else {
						String msg = xzdGp.getNum() + "已有车前往，继续等待空闲位";
						mainAction.main.sendMsgByWs(ca.getId() + "", msg);
					}
				} else {
					long i = mainAction.main.chargeDuration - cTimes;
					String msg = "充电倒计时：" + i;
					mainAction.main.sendMsgByWs(ca.getId() + "", msg);
				}

			}
		}
	}

	public void shiftAgv4zrx() {
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.ZRX.getCode());
		List<Agv> caAgvList = new ArrayList<Agv>();
		for (Park park : tempPark) {
			for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
				if (m.getValue().getLoadState() == LoadState.KK.getCode()
						&& m.getValue().getLastPoint() == park.getDot()
						&& (m.getValue().getState() == AgvState.CD.getCode()
								|| m.getValue().getState() == AgvState.DD.getCode())) {
					caAgvList.add(m.getValue());
				}
			}
		}

		if (caAgvList.size() > 0) {
			for (Agv agv : caAgvList) {
				long nowTimes = (new Date()).getTime();
				long cTimes = (nowTimes - (agv.getChargerTimes().getTime())) / 1000;
				if (cTimes > mainAction.main.chargeDuration) {
					Station station = getFreeStationByStep(Step.ZRX.getCode());
					if (station != null) {
						Park p = mainAction.getParkByStationName(station.getName());
						if (checkAgvGoal2(p, agv)) {
							Guidepost xzdNum = mainAction.getGuidepostByXZDNum(Step.ZRX.getCode());
							if (xzdNum != null) {
								Park nowPark = mainAction.getParkByDot(agv.getLastPoint());
								if (nowPark.getType() == 2) {
									agv.setGoal(xzdNum.getNum());
									joinComplete(agv.getId());
								} else {
									agv.setGoal(xzdNum.getNum());
									mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzdNum.getNum());
								}
							}
						}
					}
				} else {
					long i = mainAction.main.chargeDuration - cTimes;
					String msg = "充电倒计时：" + i;
					mainAction.main.sendMsgByWs(agv.getId() + "", msg);
				}

			}
		}
	}

	/**
	 * 向SE的工位补车辆
	 * 
	 * @param station
	 */
	public void shiftAgv4se() {
		List<Agv> cagvList = new ArrayList<Agv>();
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.SE.getCode());
		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
			Agv agv = am.getValue();
			for (Park park : tempPark) {
				if (agv.getLoadState() == LoadState.MK.getCode()
						&& (agv.getState() == AgvState.CD.getCode() || agv.getState() == AgvState.DD.getCode())
						&& agv.getLastPoint() == park.getDot()) {
					cagvList.add(agv);
				}
			}
		}
		if (cagvList.size() > 0) {
			for (Agv ca : cagvList) {
				Station station = getFreeStationByPGroup(Step.SE.getCode(), ca);
				if (station != null) {
					Park staPark = mainAction.getParkByStationName(station.getName());
					Park aPark = mainAction.getParkByDot(ca.getLastPoint());
					if (checkAgvGoal2(staPark, ca)) {
						if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
							ca.setGoal(staPark.getOutNum());
							mainAction.main.agvMap.put(ca.getId(), ca);
							mainAction.agvAction.joinComplete(ca.getId());
						} else {
							mainAction.taskAction.multiPath4z(ca, aPark.getDot(), staPark.getDot());
						}
					}
					break;
				} else {
					String msg = "SE机台无停靠点,等待！";
					mainAction.main.sendMsgByWs(ca.getId() + "", msg);
				}
//				Station qStation = getFreeStationByPGroup(Step.SE.getCode(), ca);
//				if (qStation != null) {
//					boolean isRun = true;
//					for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
//						if (m.getValue().getGoal() == qStation.getInNum() && ca.getId() != m.getValue().getId()) {
//							isRun = false;
//							String msg = "目的地有车，不能前往";
//							mainAction.main.sendMsgByWs(ca.getId() + "", msg);
//						}
//					}
//					if (isRun) {
//						qStation.setJoinAgvId(ca.getId());
//						mainAction.main.stationMap.put(qStation.getName(), qStation);
//						int end = 154;
//						Park aPark = mainAction.getParkByDot(ca.getLastPoint());
//						if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
//							ca.setGoal(end);
//							mainAction.main.agvMap.put(ca.getId(), ca);
//							mainAction.agvAction.joinComplete(ca.getId());
//						} else {
//							mainAction.taskAction.multiPath(ca, aPark.getDot(), end);
//						}
//					}
//				} else {
//					String msg = "没有SE机台要料,暂时停靠！";
//					mainAction.main.sendMsgByWs(ca.getId() + "", msg);
//				}
			}
		}
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByPGroup(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1) {
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				if (checkAgvGoal2(p, agv)) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastJoinTimeSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		} else {
			String msg = "工位已禁用或目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByPGroup(int step, Agv agv, int limit) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			Park p = mainAction.getParkByStationName(m.getValue().getName());
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1 && p.getXzdNumItem() == limit) {
				stationList.add(m.getValue());
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastJoinTimeSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		} else {
			String msg = "工位已禁用或目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比,优先选择出料多的一方
	 * 
	 * @return
	 */
	public Station getFreeStationByPGroup4OutTinity(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1) {
				boolean isFlag = true;
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				for (Map.Entry<Integer, Agv> ma : mainAction.main.agvMap.entrySet()) {
					if ((ma.getValue().getLastPoint() == p.getOutNum() || ma.getValue().getLastPoint() == p.getDot()
							|| ma.getValue().getGoal() == p.getDot() || ma.getValue().getGoal() == p.getOutNum())
							&& ma.getValue().getId() != agv.getId()) {
						isFlag = false;
					}
				}
				if (p.getTrunNum() != 0) {
					Park tp = mainAction.getParkByOutNum(p.getTrunNum());
					if (tp != null && step == m.getValue().getStep() && (m.getValue().getStep() == Step.PEB.getCode()
							|| m.getValue().getStep() == Step.PEZ.getCode()) && !checkAgvGoal(tp)) {
						isFlag = false;
					}
				}
				if (isFlag) {
					stationList.add(m.getValue());
				}
			}

		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);

		} else {
			String msg = "目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比,选择出料为10个的花篮进去
	 * 
	 * @return
	 */
	public Station getFreeStationByPGroup4OutTinityToPark(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1 && m.getValue().getOutQuantity() > 9) {
				boolean isFlag = true;
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				for (Map.Entry<Integer, Agv> ma : mainAction.main.agvMap.entrySet()) {
					if ((ma.getValue().getLastPoint() == p.getOutNum() || ma.getValue().getLastPoint() == p.getDot()
							|| ma.getValue().getGoal() == p.getDot() || ma.getValue().getGoal() == p.getOutNum())
							&& ma.getValue().getId() != agv.getId()) {
						isFlag = false;
					}
				}
				if (p.getTrunNum() != 0) {
					Park tp = mainAction.getParkByOutNum(p.getTrunNum());
					if (tp != null && (m.getValue().getStep() == Step.PEB.getCode()
							|| m.getValue().getStep() == Step.PEZ.getCode()) && checkAgvGoal(tp)) {
						isFlag = false;
					}
				}
				if (isFlag) {
					stationList.add(m.getValue());
				}
			}

		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);

		} else {
			String msg = "目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比,优先选择出料多的一方
	 * 
	 * @return
	 */
	public Station getFreeStationByPGroup4(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1) {
				boolean isFlag = true;
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				for (Map.Entry<Integer, Agv> ma : mainAction.main.agvMap.entrySet()) {
					if ((ma.getValue().getLastPoint() == p.getOutNum() || ma.getValue().getLastPoint() == p.getDot()
							|| ma.getValue().getGoal() == p.getDot() || ma.getValue().getGoal() == p.getOutNum())
							&& ma.getValue().getId() != agv.getId()) {
						isFlag = false;
					}
				}
				if (p.getTrunNum() != 0) {
					Park tp = mainAction.getParkByOutNum(p.getTrunNum());
					if (tp != null && step == m.getValue().getStep() && (m.getValue().getStep() == Step.PEB.getCode()
							|| m.getValue().getStep() == Step.PEZ.getCode()) && !checkAgvGoal(tp)) {
						isFlag = false;
					}
				}
				if (isFlag) {
					stationList.add(m.getValue());
				}
			}

		}
		if (stationList.size() > 0) {
			// 按进料的花篮数量判断
			mainAction.lastIntiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);

		} else {
			String msg = "目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByOutintitry(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1) {
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				if (checkAgvGoal2(p, agv)) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		} else {
			String msg = "目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByStepOrOutintitry(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1) {
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				if (checkAgvGoal2(p, agv)) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		} else {
			String msg = "目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByOutintitry4SwitchNum(int step, Agv agv, int SwitchNum) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1 && (m.getValue().getLimit() == SwitchNum)) {
				if (checkAgvGoal2(mainAction.getParkByStationName(m.getValue().getName()), agv)) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		} else {
			String msg = "目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 获取该工序的机台，以工序-区域-线别-优先级判别
	 * 
	 * @param step
	 * @param agv
	 * @param SwitchNum
	 * @param park
	 * @return
	 */
	public Station getFreeStationByOutintitryOrPriority4SwitchNum(int step, Agv agv, int SwitchNum, Park park) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1 && (m.getValue().getLimit() == SwitchNum)) {
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				if (checkAgvGoal2(p, agv) && p.getItem() < park.getItem()) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		} else {
			String msg = "目的地已有车辆,等待释放";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
		return station;
	}

	/**
	 * 用生产产品的型号去匹配对接机台 考虑机台是否等待AGV
	 * 
	 * @param step
	 * @param agv
	 * @return
	 */
	public Station getFreeStationByPType(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPType() == agv.getpType()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1 && m.getValue().getIsWait() == 1) {
				stationList.add(m.getValue());
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastJoinTimeSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		}
		return station;
	}

	public Station getRequireStation(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1 && m.getValue().getIsWait() == 1) {
				stationList.add(m.getValue());
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastJoinTimeSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		}
		return station;
	}

	public Station getRequireStation4KS(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getPGroup() == agv.getpGroup()
					&& (m.getValue().getJoinAgvId() == 0 || m.getValue().getJoinAgvId() == agv.getId())
					&& m.getValue().getState() == 1 && m.getValue().getIsWait2() == 1) {
				stationList.add(m.getValue());
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastJoinTimeSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		}
		return station;
	}

	/**
	 * AGV传输完成，退出对接工位
	 * 
	 * @param agvId
	 */
	public void joinComplete(int agvId) {
		boolean isRun = false;
		Agv agv = mainAction.main.agvMap.get(agvId);
		List<ControlArea> controlAreaList = getControlAreaByCoordinate(agv.getCurrentX(), agv.getCurrentY());
		if (controlAreaList.size() == 0) {// 如果AGV在非交管区域进入了交管，则向其发送启动指令
			// AGV可以退出
			isRun = true;
		} else {
			for (ControlArea ca : controlAreaList) {
				if (ca.getRunAgvId() == agvId || ca.getRunAgvId() == 0) {
					isRun = true;
					break;
				}
			}
		}
//		if(isRun){
		// 设置独占交管区标志
		if (ControlAreaFlag(agv)) {
			agv.setLineLockGroup(0);
			int type = 1;// 传输完成
			byte[] data = CommandUtil.transfer(agvId, type);
			String note = "AGV" + agvId + "对接完成回到主路";
			System.out.println(HexUtil.byte2HexStr(data) + note);
			mainAction.main.sendDataToAgv(data, note, AgvState.XS.getCode());// ctrlState,1、行驶
		} else {
			String msg = "当前所在有交管区，且有车占用，等待！";
			mainAction.main.sendMsgByWs(agv.getId() + "", msg);
		}
	}

	/**
	 * 去到下个工序的缓存区
	 * 
	 * @param agv
	 * @param station 下一个工序的机台ID
	 * @param step
	 */
	public void toNextCacheShelf(Agv agv, int step) {
		Station station = getFreeCacheStationByPGroup(step, agv.getpGroup(), 1);
		if (station != null) {
			agv.setGoal(station.getInNum());
			mainAction.main.agvMap.put(agv.getId(), agv);
			joinComplete(agv.getId());
		} else {
			Station staSE = getFreeStationByPGroup(step, agv);
			if (staSE == null) {
				Station staCacheSe = getFreeCacheStationByPGroup(step, agv.getpGroup(), 2);
				if (staCacheSe == null) {
					String msg = "没有获取到匹配线别的工位和缓存机台，需要人工介入";
					mainAction.main.sendMsgByWs(agv.getId() + "", msg);
				} else {
					agv.setGoal(staCacheSe.getInNum());
					mainAction.main.agvMap.put(agv.getId(), agv);
					joinComplete(agv.getId());
				}
			} else {
				agv.setGoal(staSE.getInNum());
				mainAction.main.agvMap.put(agv.getId(), agv);
				joinComplete(agv.getId());
			}
		}
	}

	/**
	 * 根据工序匹配没有停靠AGV的缓存机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @param step
	 * @param agv
	 * @param flag 1:缓存架出料有料和进料可存判断模式；2:缓存架只判断是否可存料 3缓存架只判断是否可取料
	 * @return
	 */
	public Station getFreeCacheStationByPGroup(int step, int pGrounp, int flag) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getType() == 3 && m.getValue().getJoinAgvId() == 0
					&& m.getValue().getState() == 1) {
				stationList.add(m.getValue());
			}
		}
		if (stationList.size() > 0) {
			for (Station sta : stationList) {
				List<CacheShelf> cacheList = mainAction.taskAction.getcacheShelf4Id(station);
				for (CacheShelf cs : cacheList) {
					if (flag == 1 && cs.getPGrounp() == pGrounp && cs.getOutFlag() == 1 && cs.getInFlag() == 1) {
						station = sta;
					} else if (flag == 2 && cs.getPGrounp() == pGrounp && cs.getInFlag() == 1) {
						station = sta;
					} else if (flag == 3 && cs.getPGrounp() == pGrounp && cs.getOutFlag() == 1) {
						station = sta;
					}
				}
			}
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByStep(int step) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getType() != 3 && m.getValue().getJoinAgvId() == 0
					&& m.getValue().getState() == 1) {
				stationList.add(m.getValue());
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastJoinTimeSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByStep2(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getType() != 3 && m.getValue().getJoinAgvId() == 0
					&& m.getValue().getState() == 1) {
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				if (checkAgvGoal2(p, agv)) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比,优先进料空蓝子少的情况
	 * 
	 * @return
	 */
	public Station getFreeStationByStep4Intinity(int step, Agv agv) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getType() != 3 && m.getValue().getJoinAgvId() == 0
					&& m.getValue().getState() == 1) {
				Park p = mainAction.getParkByStationName(m.getValue().getName());
				if (checkAgvGoal2(p, agv)) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastIntiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByStep4SwitchNum(int step, Agv agv, int switchNum) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getType() != 3 && m.getValue().getJoinAgvId() == 0
					&& m.getValue().getState() == 1 && m.getValue().getLimit() == switchNum) {
				if (checkAgvGoal(mainAction.getParkByStationName(m.getValue().getName()))) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取出料最多的机台
			station = stationList.get(0);
		}
		return station;
	}

	/**
	 * 根据工序匹配没有停靠AGV的机台 不考虑是否要车，用AGV的线别和机台的线别对比
	 * 
	 * @return
	 */
	public Station getFreeStationByStep4SwitchNumOrGrounp(int step, Agv agv, int switchNum) {
		List<Station> stationList = new ArrayList<Station>();
		Station station = null;
		for (Map.Entry<String, Station> m : mainAction.main.stationMap.entrySet()) {
			if (m.getValue().getStep() == step && m.getValue().getType() != 3 && m.getValue().getJoinAgvId() == 0
					&& m.getValue().getState() == 1 && m.getValue().getLimit() == switchNum
					&& m.getValue().getPGroup() == agv.getpGroup()) {
				if (checkAgvGoal(mainAction.getParkByStationName(m.getValue().getName()))) {
					stationList.add(m.getValue());
				}
			}
		}
		if (stationList.size() > 0) {
			// 按最后对接时间排序
			mainAction.lastOuttiSort(stationList);
			// 取最后对接时间最久的机台
			station = stationList.get(0);
		}
		return station;
	}

	/**
	 * 碱抛机台定时检测
	 */
	public void shift4jp() {
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.JPS.getCode());
		List<Agv> caAgvList = new ArrayList<Agv>();
		for (Park park : tempPark) {
			for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
				if (m.getValue().getLoadState() == LoadState.MK.getCode()
						&& m.getValue().getLastPoint() == park.getDot()
						&& (m.getValue().getState() == AgvState.CD.getCode()
								|| m.getValue().getState() == AgvState.DD.getCode())) {
					caAgvList.add(m.getValue());
				}
			}
		}

		if (caAgvList.size() > 0) {
			for (Agv agv : caAgvList) {
				long nowTimes = (new Date()).getTime();// 获取当前时间
				long cTimes = (nowTimes - (agv.getChargerTimes().getTime())) / 1000;// 充电开始时间
				// 强制igv进行一定时间的充电。
				if (cTimes > (Main.lowBatteryChargerTimes * 60)) {
					Guidepost xzdNum = mainAction.getGuidepostByXZDNum(Step.KSX.getCode(), 0);// 根据工序，区域获得选择点，区域默认为0
					if (xzdNum != null) {// 如果选择点不为空
						Park nowPark = mainAction.getParkByDot(agv.getLastPoint());// 根据地标获得泊位（上次到达的地标）
						agv.setGoal(xzdNum.getNum());// agv的目标泊位（选择点的地标号）
						if (nowPark.getType() == 2) {// 如果工序类型等于充电桩
							joinComplete(agv.getId());// 先推出工位
						} else {
							mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzdNum.getNum());// 下发多段路线
						}
					}
				} else {
					long i = Main.lowBatteryChargerTimes * 60 - cTimes;// i = 低电量充电时间减掉充电开始时间
					String msg = "充电倒计时： " + i;
					mainAction.main.sendMsgByWs(agv.getId() + "", msg);
				}
//				Station station = getFreeStationByPGroup4OutTinity(Step.JPS.getCode(), agv);
//				if (station != null) {
//					Park park = mainAction.getParkByStationName(station.getName());
//					if (checkAgvGoal2(park, agv)) {
//						Park nowPark = mainAction.getParkByDot(agv.getLastPoint());
//						if (nowPark.getType() == 2) {
//							agv.setGoal(park.getOutNum());
//							joinComplete(agv.getId());
//						} else {
//							agv.setGoal(park.getOutNum());
//							mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), park.getOutNum());
//						}
//					}
//				}
			}
		}

	}

	/**
	 * 定时检测扩散机台是否有需求，从待命位叫车过去机台
	 */
	public void shiftAgv4kss() {
		List<Agv> cagvList = new ArrayList<Agv>();
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.KSS.getCode());
		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
			Agv agv = am.getValue();
			for (Park park : tempPark) {
				if (agv.getLoadState() == LoadState.KM.getCode()
						&& (agv.getState() == AgvState.CD.getCode() || agv.getState() == AgvState.DD.getCode())
						&& agv.getLastPoint() == park.getDot()) {
					cagvList.add(agv);
				}
			}
		}
		if (cagvList.size() > 0) {
			for (Agv ca : cagvList) {
				long nowTimes = (new Date()).getTime();
				long cTimes = (nowTimes - (ca.getChargerTimes().getTime())) / 1000;
				if (cTimes > mainAction.main.chargeDuration) {
					Park aPark = mainAction.getParkByDot(ca.getLastPoint());
					// 制绒线的前一个充电桩
					if (aPark.getSubType() == 1) {
						Guidepost xzdNum = mainAction.getGuidepostByStep2(Step.KSS.getCode(), 0);
						if (xzdNum != null) {
							ca.setGoal(xzdNum.getNum());
							if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
								mainAction.main.agvMap.put(ca.getId(), ca);
								mainAction.agvAction.joinComplete(ca.getId());
							} else {
								mainAction.taskAction.multiPath4z(ca, aPark.getDot(), xzdNum.getNum());
							}
						}
					} else {
						// 获取机台
						Station station = getFreeStationByOutintitryOrPriority4SwitchNum(Step.KSS.getCode(), ca,
								aPark.getXzdNumItem(), aPark);
						if (station != null) {
							Park p = mainAction.getParkByStationName(station.getName());
							ca.setGoal(p.getOutNum());
							if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
								mainAction.main.agvMap.put(ca.getId(), ca);
								mainAction.agvAction.joinComplete(ca.getId());
							} else {
								mainAction.taskAction.multiPath4z(ca, aPark.getDot(), p.getOutNum());
							}
						}

					}

				} else {
					String msg = "扩散机台无停靠点,等待！";
					mainAction.main.sendMsgByWs(ca.getId() + "", msg);
				}
			}
		}

	}

	/**
	 * 定时检测扩散机台是否有需求，从待命位叫车过去机台
	 */
	public void shiftAgv4ksx() {
		List<Agv> cagvList = new ArrayList<Agv>();
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.KSX.getCode());
		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
			Agv agv = am.getValue();
			for (Park park : tempPark) {
				if (/*
					 * agv.getLoadState() == LoadState.KM.getCode() &&
					 */ (agv.getState() == AgvState.CD.getCode() || agv.getState() == AgvState.DD.getCode())
						&& agv.getLastPoint() == park.getDot()) {
					cagvList.add(agv);
				}
			}
		}
		if (cagvList.size() > 0) {
			for (Agv ca : cagvList) {
				Park aPark = mainAction.getParkByDot(ca.getLastPoint());
				Station station = getFreeStationByPGroup(Step.KSX.getCode(), ca, aPark.getXzdNumItem());
				long nowTimes = (new Date()).getTime();
				long cTimes = (nowTimes - (ca.getChargerTimes().getTime())) / 1000;
				if (cTimes > mainAction.main.chargeDuration) {
					if (station != null) {
						Park staPark = mainAction.getParkByStationName(station.getName());
						if (checkAgvGoal2(staPark, ca)) {
							if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
								ca.setGoal(staPark.getOutNum());
								mainAction.main.agvMap.put(ca.getId(), ca);
								mainAction.agvAction.joinComplete(ca.getId());
							} else {
								mainAction.taskAction.multiPath4z(ca, aPark.getDot(), staPark.getDot());
							}
						}
						break;
					} else {
						String msg = "扩散机台无停靠点,等待！";
						mainAction.main.sendMsgByWs(ca.getId() + "", msg);
					}
				} else {
					long i = mainAction.main.chargeDuration - cTimes;
					String msg = "充电倒计时：" + i;
					mainAction.main.sendMsgByWs(ca.getId() + "", msg);
				}

			}
		}

	}

	/**
	 * 定时检测前氧机台是否有需求，从待命位叫车过去机台
	 */
	public void shiftAgv4qy() {
		List<Agv> cagvList = new ArrayList<Agv>();
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.QY.getCode());
		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
			Agv agv = am.getValue();
			for (Park park : tempPark) {
				if (agv.getLoadState() == LoadState.KM.getCode()
						&& (agv.getState() == AgvState.CD.getCode() || agv.getState() == AgvState.DD.getCode())
						&& agv.getLastPoint() == park.getDot()) {
					cagvList.add(agv);
				}
			}
		}
		if (cagvList.size() > 0) {
			for (Agv ca : cagvList) {
				Station station = getFreeStationByPGroup(Step.QY.getCode(), ca);
				if (station != null) {
					Park staPark = mainAction.getParkByStationName(station.getName());
					Park aPark = mainAction.getParkByDot(ca.getLastPoint());
					if (checkAgvGoal2(staPark, ca)) {
						if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
							ca.setGoal(staPark.getOutNum());
							mainAction.main.agvMap.put(ca.getId(), ca);
							mainAction.agvAction.joinComplete(ca.getId());
						} else {
							mainAction.taskAction.multiPath4z(ca, aPark.getDot(), staPark.getDot());
						}
					}
					break;
				} else {
					String msg = "前氧机台无停靠点,等待！";
					mainAction.main.sendMsgByWs(ca.getId() + "", msg);
				}
			}
		}

	}

	/**
	 * 定时检测后氧机台是否有需求，从待命位叫车过去机台
	 * 
	 */
	public void shiftAgv4hy() {
		List<Agv> cagvList = new ArrayList<Agv>();
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.HYS.getCode());
		for (Map.Entry<Integer, Agv> am : mainAction.main.agvMap.entrySet()) {
			Agv agv = am.getValue();
			for (Park park : tempPark) {
				if ((agv.getState() == AgvState.CD.getCode() || agv.getState() == AgvState.DD.getCode())
						&& agv.getLastPoint() == park.getDot()) {
					cagvList.add(agv);
				}
			}
		}
		if (cagvList.size() > 0) {
			for (Agv ca : cagvList) {
				Park aPark = mainAction.getParkByDot(ca.getLastPoint());
				long nowTimes = (new Date()).getTime();
				long cTimes = (nowTimes - (ca.getChargerTimes().getTime())) / 1000;

				// 充电结束
				boolean isGo = false;

				// 低电量开启充电时长
				if (ca.isLowCharger() && cTimes > (Main.lowBatteryChargerTimes * 60)) {
					isGo = true;
				} else if (!ca.isLowCharger() && cTimes > mainAction.main.chargeDuration) {
					isGo = true;
				}

				if (isGo) {
					Station station = getFreeStationByOutintitry4SwitchNum(Step.HYS.getCode(), ca,
							aPark.getXzdNumItem());
					if (aPark.getSubType() == 1) {
						station = getFreeStationByOutintitry(Step.HYS.getCode(), ca);
					}

					if (station != null) {
						Park staPark = mainAction.getParkByStationName(station.getName());
						Guidepost xzdNum = mainAction.getGuidepostByStep2(Step.HYS.getCode(), station.getLimit());
						if (checkAgvGoal2(xzdNum.getNum(), ca)) {
							ca.setGoal(xzdNum.getNum());
							if (aPark.getType() == 2) {// 如果是充电桩要先退出工位
								mainAction.main.agvMap.put(ca.getId(), ca);
								mainAction.agvAction.joinComplete(ca.getId());
							} else {
								mainAction.taskAction.multiPath4z(ca, aPark.getDot(), staPark.getDot());
							}
						}
						break;
					} else {
						String msg = "后氧机台无停靠点,等待！";
						mainAction.main.sendMsgByWs(ca.getId() + "", msg);
					}
				} else {
					long i = Main.lowBatteryChargerTimes * 60 - cTimes;
					if (!ca.isLowCharger()) {
						i = mainAction.main.chargeDuration - cTimes;
					}
					String msg = "充电倒计时：" + i;
					mainAction.main.sendMsgByWs(ca.getId() + "", msg);
				}
			}
		}

	}

	/**
	 * 碱抛返空机台定时检测
	 */
	public void shift4jpfk() {
		List<Park> tempPark = mainAction.taskAction.getTempPark(Step.JPFK.getCode());
		List<Agv> caAgvList = new ArrayList<Agv>();
		for (Park park : tempPark) {
			for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
				if (m.getValue().getLoadState() == LoadState.KM.getCode()
						&& m.getValue().getLastPoint() == park.getDot()
						&& (m.getValue().getState() == AgvState.CD.getCode()
								|| m.getValue().getState() == AgvState.DD.getCode())) {
					caAgvList.add(m.getValue());
				}
			}
		}

		if (caAgvList.size() > 0) {
			for (Agv agv : caAgvList) {
//				Station station = getFreeStationByPGroup4OutTinity(Step.JPFK.getCode(), agv);
				Station station = getFreeStationByStep4Intinity(Step.JPFK.getCode(), agv);
				if (station != null) {
					Park park = mainAction.getParkByStationName(station.getName());
					if (checkAgvGoal2(park, agv)) {
						Park nowPark = mainAction.getParkByDot(agv.getLastPoint());
						if (nowPark.getType() == 2) {
							agv.setGoal(park.getOutNum());
							joinComplete(agv.getId());
						} else {
							agv.setGoal(park.getOutNum());
							mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), park.getOutNum());
						}
					}
				}
			}
		}

	}

	/**
	 * 充电桩定时充电机制
	 */
	public void shift4KSCharger() {
		List<Park> tempPark = mainAction.taskAction.getTempPark(998);
		List<Agv> caAgvList = new ArrayList<Agv>();
		// 获取充电桩(公共点充电桩，可被多个工序的车充电)上的igv车号
		for (Park park : tempPark) {
			for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
				if (m.getValue().getLastPoint() == park.getDot() && (m.getValue().getState() == AgvState.CD.getCode()
						|| m.getValue().getState() == AgvState.DD.getCode())) {
					caAgvList.add(m.getValue());
				}
			}
		}

		if (caAgvList.size() > 0) {
			for (Agv agv : caAgvList) {
				long nowTimes = (new Date()).getTime();
				long cTimes = (nowTimes - (agv.getChargerTimes().getTime())) / 1000;
				Park nowPark = mainAction.getParkByDot(agv.getLastPoint());
				// 强制igv进行一定时间的充电。
				if (cTimes > (Main.lowBatteryChargerTimes * 60)) {
					if (agv.getNextStep() == Step.ZRS.getCode()) {
						Guidepost xzdNum = mainAction.getGuidepostByXZDNum(agv.getIsStep());
						if (xzdNum != null /* && checkAgvGoal2(xzdNum.getNum(), agv) */) {
							agv.setGoal(xzdNum.getNum());
							if (nowPark.getType() == 2) {
								joinComplete(agv.getId());
							} else {
								mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzdNum.getNum());
							}
						}
					} else if (agv.getNextStep() == Step.KSS.getCode()) {
						Station station = getFreeStationByOutintitry4SwitchNum(agv.getNextStep(), agv,
								nowPark.getXzdNumItem());
						if (station != null) {
							Park p = mainAction.getParkByStationName(station.getName());
							agv.setGoal(p.getOutNum());
							if (nowPark.getType() == 2) {
								joinComplete(agv.getId());
							} else {
								mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), p.getOutNum());
							}
						}
					}

				} else {
					long i = Main.lowBatteryChargerTimes * 60 - cTimes;
					String msg = "充电倒计时：" + i;
					mainAction.main.sendMsgByWs(agv.getId() + "", msg);
				}

			}
		}
	}

	/**
	 * 行驶前判断交管区是否有车辆，若有暂不行驶
	 * 
	 * @param agv
	 * @return true=可通行，false=不可通行
	 */
	public boolean ControlAreaFlag(Agv agv) {
		// 放行标志
		boolean isFlag = true;
		Double pointLon = Double.valueOf(agv.getCurrentX());// 纬度（横坐标）
		Double pointLat = Double.valueOf(agv.getCurrentY());// 经度(纵坐标)
		List<ControlArea> controlAreaList = getControlAreaByCoordinate(pointLon, pointLat);
		if (controlAreaList.size() > 0) {
			for (ControlArea controlArea : controlAreaList) {
				if (controlArea.getRunAgvList().size() > 0) {
					for (ControlRunAgv cagv : controlArea.getRunAgvList()) {
						// 如果当前交管区包含该小车，则放行
						if (cagv.getAgvId() == agv.getId()) {
							return true;
						}
					}
					isFlag = false;
				}
			}
		}
		return isFlag;
	}

	public void shift4qyCharger() {
		List<Park> tempPark = mainAction.taskAction.getTempPark(997);
		List<Agv> caAgvList = new ArrayList<Agv>();
		// 获取充电桩(公共点充电桩，可被多个工序的车充电)上的igv车号
		for (Park park : tempPark) {
			for (Map.Entry<Integer, Agv> m : mainAction.main.agvMap.entrySet()) {
				if (m.getValue().getLastPoint() == park.getDot() && (m.getValue().getState() == AgvState.CD.getCode()
						|| m.getValue().getState() == AgvState.DD.getCode())) {
					caAgvList.add(m.getValue());
				}
			}
		}

		if (caAgvList.size() > 0) {
			for (Agv agv : caAgvList) {
				long nowTimes = (new Date()).getTime();// 获取当前时间
				long cTimes = (nowTimes - (agv.getChargerTimes().getTime())) / 1000;// 充电开始的时间
				// 强制igv进行一定时间的充电。
				if (cTimes > (Main.lowBatteryChargerTimes * 60)) {
					Guidepost xzdNum = mainAction.getGuidepostByXZDNum(Step.JPS.getCode(), 0);
					if (xzdNum != null) {
						Park nowPark = mainAction.getParkByDot(agv.getLastPoint());
						agv.setGoal(xzdNum.getNum());
						if (nowPark.getType() == 2) {
							joinComplete(agv.getId());
						} else {
							mainAction.taskAction.multiPath4z(agv, agv.getLastPoint(), xzdNum.getNum());
						}
					}
				} else {
					long i = Main.lowBatteryChargerTimes * 60 - cTimes;
					String msg = "充电倒计时：" + i;
					mainAction.main.sendMsgByWs(agv.getId() + "", msg);
				}

			}
		}
	}
}